aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/9p/9p.h9
-rw-r--r--fs/9p/Makefile10
-rw-r--r--fs/9p/conv.c13
-rw-r--r--fs/9p/conv.h8
-rw-r--r--fs/9p/debug.h6
-rw-r--r--fs/9p/error.c5
-rw-r--r--fs/9p/error.h5
-rw-r--r--fs/9p/fcall.c (renamed from fs/9p/9p.c)20
-rw-r--r--fs/9p/fcprint.c346
-rw-r--r--fs/9p/fid.c5
-rw-r--r--fs/9p/fid.h5
-rw-r--r--fs/9p/mux.c32
-rw-r--r--fs/9p/mux.h5
-rw-r--r--fs/9p/trans_fd.c301
-rw-r--r--fs/9p/trans_sock.c334
-rw-r--r--fs/9p/transport.h5
-rw-r--r--fs/9p/v9fs.c15
-rw-r--r--fs/9p/v9fs.h8
-rw-r--r--fs/9p/v9fs_vfs.h5
-rw-r--r--fs/9p/vfs_addr.c5
-rw-r--r--fs/9p/vfs_dentry.c7
-rw-r--r--fs/9p/vfs_dir.c5
-rw-r--r--fs/9p/vfs_file.c37
-rw-r--r--fs/9p/vfs_inode.c56
-rw-r--r--fs/9p/vfs_super.c7
-rw-r--r--fs/aio.c3
-rw-r--r--fs/binfmt_elf.c5
-rw-r--r--fs/binfmt_flat.c73
-rw-r--r--fs/bio.c7
-rw-r--r--fs/buffer.c30
-rw-r--r--fs/char_dev.c7
-rw-r--r--fs/compat.c8
-rw-r--r--fs/dcache.c20
-rw-r--r--fs/direct-io.c8
-rw-r--r--fs/eventpoll.c4
-rw-r--r--fs/exec.c7
-rw-r--r--fs/ext2/super.c2
-rw-r--r--fs/ext3/bitmap.c6
-rw-r--r--fs/fs-writeback.c2
-rw-r--r--fs/inode.c2
-rw-r--r--fs/inotify.c87
-rw-r--r--fs/jbd/journal.c27
-rw-r--r--fs/jbd/transaction.c4
-rw-r--r--fs/minix/bitmap.c10
-rw-r--r--fs/minix/inode.c26
-rw-r--r--fs/minix/itree_v1.c4
-rw-r--r--fs/minix/itree_v2.c4
-rw-r--r--fs/namei.c22
-rw-r--r--fs/open.c4
-rw-r--r--fs/pipe.c3
-rw-r--r--fs/proc/proc_misc.c37
-rw-r--r--fs/read_write.c2
-rw-r--r--fs/reiserfs/file.c10
-rw-r--r--fs/reiserfs/fix_node.c4
-rw-r--r--fs/reiserfs/item_ops.c2
-rw-r--r--fs/reiserfs/journal.c21
-rw-r--r--fs/reiserfs/stree.c210
-rw-r--r--fs/reiserfs/super.c8
-rw-r--r--fs/reiserfs/xattr_acl.c4
-rw-r--r--fs/smbfs/inode.c2
-rw-r--r--fs/super.c3
-rw-r--r--fs/udf/inode.c6
62 files changed, 1070 insertions, 868 deletions
diff --git a/fs/9p/9p.h b/fs/9p/9p.h
index 95d72aec1c1a..94e2f92ab2e8 100644
--- a/fs/9p/9p.h
+++ b/fs/9p/9p.h
@@ -8,9 +8,8 @@
8 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 8 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License version 2
12 * the Free Software Foundation; either version 2 of the License, or 12 * as published by the Free Software Foundation.
13 * (at your option) any later version.
14 * 13 *
15 * This program is distributed in the hope that it will be useful, 14 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -235,6 +234,7 @@ struct Tcreate {
235 struct v9fs_str name; 234 struct v9fs_str name;
236 u32 perm; 235 u32 perm;
237 u8 mode; 236 u8 mode;
237 struct v9fs_str extension;
238}; 238};
239 239
240struct Rcreate { 240struct Rcreate {
@@ -364,7 +364,7 @@ int v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid,
364 struct v9fs_fcall **rcall); 364 struct v9fs_fcall **rcall);
365 365
366int v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, 366int v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name,
367 u32 perm, u8 mode, struct v9fs_fcall **rcall); 367 u32 perm, u8 mode, char *extension, struct v9fs_fcall **rcall);
368 368
369int v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid, 369int v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid,
370 u64 offset, u32 count, struct v9fs_fcall **rcall); 370 u64 offset, u32 count, struct v9fs_fcall **rcall);
@@ -372,3 +372,4 @@ int v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid,
372int v9fs_t_write(struct v9fs_session_info *v9ses, u32 fid, u64 offset, 372int v9fs_t_write(struct v9fs_session_info *v9ses, u32 fid, u64 offset,
373 u32 count, const char __user * data, 373 u32 count, const char __user * data,
374 struct v9fs_fcall **rcall); 374 struct v9fs_fcall **rcall);
375int v9fs_printfcall(char *, int, struct v9fs_fcall *, int);
diff --git a/fs/9p/Makefile b/fs/9p/Makefile
index 2f4ce43f7b6c..87897f84dfb6 100644
--- a/fs/9p/Makefile
+++ b/fs/9p/Makefile
@@ -1,10 +1,9 @@
1obj-$(CONFIG_9P_FS) := 9p2000.o 1obj-$(CONFIG_9P_FS) := 9p.o
2 2
39p2000-objs := \ 39p-objs := \
4 trans_fd.o \ 4 trans_fd.o \
5 trans_sock.o \
6 mux.o \ 5 mux.o \
7 9p.o \ 6 fcall.o \
8 conv.o \ 7 conv.o \
9 vfs_super.o \ 8 vfs_super.o \
10 vfs_inode.o \ 9 vfs_inode.o \
@@ -14,5 +13,6 @@ obj-$(CONFIG_9P_FS) := 9p2000.o
14 vfs_dentry.o \ 13 vfs_dentry.o \
15 error.o \ 14 error.o \
16 v9fs.o \ 15 v9fs.o \
17 fid.o 16 fid.o \
17 fcprint.o
18 18
diff --git a/fs/9p/conv.c b/fs/9p/conv.c
index bba817142465..a767e05b60bf 100644
--- a/fs/9p/conv.c
+++ b/fs/9p/conv.c
@@ -8,9 +8,8 @@
8 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 8 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License version 2
12 * the Free Software Foundation; either version 2 of the License, or 12 * as published by the Free Software Foundation.
13 * (at your option) any later version.
14 * 13 *
15 * This program is distributed in the hope that it will be useful, 14 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -666,7 +665,8 @@ struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode)
666 return fc; 665 return fc;
667} 666}
668 667
669struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode) 668struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode,
669 char *extension, int extended)
670{ 670{
671 int size; 671 int size;
672 struct v9fs_fcall *fc; 672 struct v9fs_fcall *fc;
@@ -674,6 +674,9 @@ struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode)
674 struct cbuf *bufp = &buffer; 674 struct cbuf *bufp = &buffer;
675 675
676 size = 4 + 2 + strlen(name) + 4 + 1; /* fid[4] name[s] perm[4] mode[1] */ 676 size = 4 + 2 + strlen(name) + 4 + 1; /* fid[4] name[s] perm[4] mode[1] */
677 if (extended && extension!=NULL)
678 size += 2 + strlen(extension); /* extension[s] */
679
677 fc = v9fs_create_common(bufp, size, TCREATE); 680 fc = v9fs_create_common(bufp, size, TCREATE);
678 if (IS_ERR(fc)) 681 if (IS_ERR(fc))
679 goto error; 682 goto error;
@@ -682,6 +685,8 @@ struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode)
682 v9fs_put_str(bufp, name, &fc->params.tcreate.name); 685 v9fs_put_str(bufp, name, &fc->params.tcreate.name);
683 v9fs_put_int32(bufp, perm, &fc->params.tcreate.perm); 686 v9fs_put_int32(bufp, perm, &fc->params.tcreate.perm);
684 v9fs_put_int8(bufp, mode, &fc->params.tcreate.mode); 687 v9fs_put_int8(bufp, mode, &fc->params.tcreate.mode);
688 if (extended)
689 v9fs_put_str(bufp, extension, &fc->params.tcreate.extension);
685 690
686 if (buf_check_overflow(bufp)) { 691 if (buf_check_overflow(bufp)) {
687 kfree(fc); 692 kfree(fc);
diff --git a/fs/9p/conv.h b/fs/9p/conv.h
index f5896628dae4..dd5b6b1b610f 100644
--- a/fs/9p/conv.h
+++ b/fs/9p/conv.h
@@ -8,9 +8,8 @@
8 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 8 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License version 2
12 * the Free Software Foundation; either version 2 of the License, or 12 * as published by the Free Software Foundation.
13 * (at your option) any later version.
14 * 13 *
15 * This program is distributed in the hope that it will be useful, 14 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -39,7 +38,8 @@ struct v9fs_fcall *v9fs_create_tflush(u16 oldtag);
39struct v9fs_fcall *v9fs_create_twalk(u32 fid, u32 newfid, u16 nwname, 38struct v9fs_fcall *v9fs_create_twalk(u32 fid, u32 newfid, u16 nwname,
40 char **wnames); 39 char **wnames);
41struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode); 40struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode);
42struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode); 41struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode,
42 char *extension, int extended);
43struct v9fs_fcall *v9fs_create_tread(u32 fid, u64 offset, u32 count); 43struct v9fs_fcall *v9fs_create_tread(u32 fid, u64 offset, u32 count);
44struct v9fs_fcall *v9fs_create_twrite(u32 fid, u64 offset, u32 count, 44struct v9fs_fcall *v9fs_create_twrite(u32 fid, u64 offset, u32 count,
45 const char __user *data); 45 const char __user *data);
diff --git a/fs/9p/debug.h b/fs/9p/debug.h
index fe551032788b..4228c0bb3c32 100644
--- a/fs/9p/debug.h
+++ b/fs/9p/debug.h
@@ -5,9 +5,8 @@
5 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 5 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License version 2
9 * the Free Software Foundation; either version 2 of the License, or 9 * as published by the Free Software Foundation.
10 * (at your option) any later version.
11 * 10 *
12 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -30,6 +29,7 @@
30#define DEBUG_MUX (1<<5) 29#define DEBUG_MUX (1<<5)
31#define DEBUG_TRANS (1<<6) 30#define DEBUG_TRANS (1<<6)
32#define DEBUG_SLABS (1<<7) 31#define DEBUG_SLABS (1<<7)
32#define DEBUG_FCALL (1<<8)
33 33
34#define DEBUG_DUMP_PKT 0 34#define DEBUG_DUMP_PKT 0
35 35
diff --git a/fs/9p/error.c b/fs/9p/error.c
index e4b6f8f38b6f..981fe8ecd780 100644
--- a/fs/9p/error.c
+++ b/fs/9p/error.c
@@ -11,9 +11,8 @@
11 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 11 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by 14 * it under the terms of the GNU General Public License version 2
15 * the Free Software Foundation; either version 2 of the License, or 15 * as published by the Free Software Foundation.
16 * (at your option) any later version.
17 * 16 *
18 * This program is distributed in the hope that it will be useful, 17 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/fs/9p/error.h b/fs/9p/error.h
index a9794e85fe51..5f3ca522b316 100644
--- a/fs/9p/error.h
+++ b/fs/9p/error.h
@@ -12,9 +12,8 @@
12 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 12 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
13 * 13 *
14 * This program is free software; you can redistribute it and/or modify 14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by 15 * it under the terms of the GNU General Public License version 2
16 * the Free Software Foundation; either version 2 of the License, or 16 * as published by the Free Software Foundation.
17 * (at your option) any later version.
18 * 17 *
19 * This program is distributed in the hope that it will be useful, 18 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/fs/9p/9p.c b/fs/9p/fcall.c
index c148e6ba07e5..71742ba150c4 100644
--- a/fs/9p/9p.c
+++ b/fs/9p/fcall.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/fs/9p/9p.c 2 * linux/fs/9p/fcall.c
3 * 3 *
4 * This file contains functions to perform synchronous 9P calls 4 * This file contains functions to perform synchronous 9P calls
5 * 5 *
@@ -8,9 +8,8 @@
8 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 8 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License version 2
12 * the Free Software Foundation; either version 2 of the License, or 12 * as published by the Free Software Foundation.
13 * (at your option) any later version.
14 * 13 *
15 * This program is distributed in the hope that it will be useful, 14 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -152,10 +151,9 @@ v9fs_t_clunk(struct v9fs_session_info *v9ses, u32 fid)
152/** 151/**
153 * v9fs_v9fs_t_flush - flush a pending transaction 152 * v9fs_v9fs_t_flush - flush a pending transaction
154 * @v9ses: 9P2000 session information 153 * @v9ses: 9P2000 session information
155 * @tag: tid to release 154 * @tag: tag to release
156 * 155 *
157 */ 156 */
158
159int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 oldtag) 157int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 oldtag)
160{ 158{
161 int ret; 159 int ret;
@@ -172,7 +170,7 @@ int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 oldtag)
172 170
173 return ret; 171 return ret;
174} 172}
175#endif /* 0 */ 173#endif
176 174
177/** 175/**
178 * v9fs_t_stat - read a file's meta-data 176 * v9fs_t_stat - read a file's meta-data
@@ -334,8 +332,8 @@ v9fs_t_remove(struct v9fs_session_info *v9ses, u32 fid,
334 */ 332 */
335 333
336int 334int
337v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, 335v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, u32 perm,
338 u32 perm, u8 mode, struct v9fs_fcall **rcp) 336 u8 mode, char *extension, struct v9fs_fcall **rcp)
339{ 337{
340 int ret; 338 int ret;
341 struct v9fs_fcall *tc; 339 struct v9fs_fcall *tc;
@@ -343,7 +341,9 @@ v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name,
343 dprintk(DEBUG_9P, "fid %d name '%s' perm %x mode %d\n", 341 dprintk(DEBUG_9P, "fid %d name '%s' perm %x mode %d\n",
344 fid, name, perm, mode); 342 fid, name, perm, mode);
345 343
346 tc = v9fs_create_tcreate(fid, name, perm, mode); 344 tc = v9fs_create_tcreate(fid, name, perm, mode, extension,
345 v9ses->extended);
346
347 if (!IS_ERR(tc)) { 347 if (!IS_ERR(tc)) {
348 ret = v9fs_mux_rpc(v9ses->mux, tc, rcp); 348 ret = v9fs_mux_rpc(v9ses->mux, tc, rcp);
349 kfree(tc); 349 kfree(tc);
diff --git a/fs/9p/fcprint.c b/fs/9p/fcprint.c
new file mode 100644
index 000000000000..583e827baebd
--- /dev/null
+++ b/fs/9p/fcprint.c
@@ -0,0 +1,346 @@
1/*
2 * linux/fs/9p/fcprint.c
3 *
4 * Print 9P call.
5 *
6 * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to:
19 * Free Software Foundation
20 * 51 Franklin Street, Fifth Floor
21 * Boston, MA 02111-1301 USA
22 *
23 */
24#include <linux/config.h>
25#include <linux/module.h>
26#include <linux/errno.h>
27#include <linux/fs.h>
28#include <linux/idr.h>
29
30#include "debug.h"
31#include "v9fs.h"
32#include "9p.h"
33#include "mux.h"
34
35static int
36v9fs_printqid(char *buf, int buflen, struct v9fs_qid *q)
37{
38 int n;
39 char b[10];
40
41 n = 0;
42 if (q->type & V9FS_QTDIR)
43 b[n++] = 'd';
44 if (q->type & V9FS_QTAPPEND)
45 b[n++] = 'a';
46 if (q->type & V9FS_QTAUTH)
47 b[n++] = 'A';
48 if (q->type & V9FS_QTEXCL)
49 b[n++] = 'l';
50 if (q->type & V9FS_QTTMP)
51 b[n++] = 't';
52 if (q->type & V9FS_QTSYMLINK)
53 b[n++] = 'L';
54 b[n] = '\0';
55
56 return scnprintf(buf, buflen, "(%.16llx %x %s)", (long long int) q->path,
57 q->version, b);
58}
59
60static int
61v9fs_printperm(char *buf, int buflen, int perm)
62{
63 int n;
64 char b[15];
65
66 n = 0;
67 if (perm & V9FS_DMDIR)
68 b[n++] = 'd';
69 if (perm & V9FS_DMAPPEND)
70 b[n++] = 'a';
71 if (perm & V9FS_DMAUTH)
72 b[n++] = 'A';
73 if (perm & V9FS_DMEXCL)
74 b[n++] = 'l';
75 if (perm & V9FS_DMTMP)
76 b[n++] = 't';
77 if (perm & V9FS_DMDEVICE)
78 b[n++] = 'D';
79 if (perm & V9FS_DMSOCKET)
80 b[n++] = 'S';
81 if (perm & V9FS_DMNAMEDPIPE)
82 b[n++] = 'P';
83 if (perm & V9FS_DMSYMLINK)
84 b[n++] = 'L';
85 b[n] = '\0';
86
87 return scnprintf(buf, buflen, "%s%03o", b, perm&077);
88}
89
90static int
91v9fs_printstat(char *buf, int buflen, struct v9fs_stat *st, int extended)
92{
93 int n;
94
95 n = scnprintf(buf, buflen, "'%.*s' '%.*s'", st->name.len,
96 st->name.str, st->uid.len, st->uid.str);
97 if (extended)
98 n += scnprintf(buf+n, buflen-n, "(%d)", st->n_uid);
99
100 n += scnprintf(buf+n, buflen-n, " '%.*s'", st->gid.len, st->gid.str);
101 if (extended)
102 n += scnprintf(buf+n, buflen-n, "(%d)", st->n_gid);
103
104 n += scnprintf(buf+n, buflen-n, " '%.*s'", st->muid.len, st->muid.str);
105 if (extended)
106 n += scnprintf(buf+n, buflen-n, "(%d)", st->n_muid);
107
108 n += scnprintf(buf+n, buflen-n, " q ");
109 n += v9fs_printqid(buf+n, buflen-n, &st->qid);
110 n += scnprintf(buf+n, buflen-n, " m ");
111 n += v9fs_printperm(buf+n, buflen-n, st->mode);
112 n += scnprintf(buf+n, buflen-n, " at %d mt %d l %lld",
113 st->atime, st->mtime, (long long int) st->length);
114
115 if (extended)
116 n += scnprintf(buf+n, buflen-n, " ext '%.*s'",
117 st->extension.len, st->extension.str);
118
119 return n;
120}
121
122static int
123v9fs_dumpdata(char *buf, int buflen, u8 *data, int datalen)
124{
125 int i, n;
126
127 i = n = 0;
128 while (i < datalen) {
129 n += scnprintf(buf + n, buflen - n, "%02x", data[i]);
130 if (i%4 == 3)
131 n += scnprintf(buf + n, buflen - n, " ");
132 if (i%32 == 31)
133 n += scnprintf(buf + n, buflen - n, "\n");
134
135 i++;
136 }
137 n += scnprintf(buf + n, buflen - n, "\n");
138
139 return n;
140}
141
142static int
143v9fs_printdata(char *buf, int buflen, u8 *data, int datalen)
144{
145 return v9fs_dumpdata(buf, buflen, data, datalen<16?datalen:16);
146}
147
148int
149v9fs_printfcall(char *buf, int buflen, struct v9fs_fcall *fc, int extended)
150{
151 int i, ret, type, tag;
152
153 if (!fc)
154 return scnprintf(buf, buflen, "<NULL>");
155
156 type = fc->id;
157 tag = fc->tag;
158
159 ret = 0;
160 switch (type) {
161 case TVERSION:
162 ret += scnprintf(buf+ret, buflen-ret,
163 "Tversion tag %u msize %u version '%.*s'", tag,
164 fc->params.tversion.msize, fc->params.tversion.version.len,
165 fc->params.tversion.version.str);
166 break;
167
168 case RVERSION:
169 ret += scnprintf(buf+ret, buflen-ret,
170 "Rversion tag %u msize %u version '%.*s'", tag,
171 fc->params.rversion.msize, fc->params.rversion.version.len,
172 fc->params.rversion.version.str);
173 break;
174
175 case TAUTH:
176 ret += scnprintf(buf+ret, buflen-ret,
177 "Tauth tag %u afid %d uname '%.*s' aname '%.*s'", tag,
178 fc->params.tauth.afid, fc->params.tauth.uname.len,
179 fc->params.tauth.uname.str, fc->params.tauth.aname.len,
180 fc->params.tauth.aname.str);
181 break;
182
183 case RAUTH:
184 ret += scnprintf(buf+ret, buflen-ret, "Rauth tag %u qid ", tag);
185 v9fs_printqid(buf+ret, buflen-ret, &fc->params.rauth.qid);
186 break;
187
188 case TATTACH:
189 ret += scnprintf(buf+ret, buflen-ret,
190 "Tattach tag %u fid %d afid %d uname '%.*s' aname '%.*s'",
191 tag, fc->params.tattach.fid, fc->params.tattach.afid,
192 fc->params.tattach.uname.len, fc->params.tattach.uname.str,
193 fc->params.tattach.aname.len, fc->params.tattach.aname.str);
194 break;
195
196 case RATTACH:
197 ret += scnprintf(buf+ret, buflen-ret, "Rattach tag %u qid ", tag);
198 v9fs_printqid(buf+ret, buflen-ret, &fc->params.rattach.qid);
199 break;
200
201 case RERROR:
202 ret += scnprintf(buf+ret, buflen-ret, "Rerror tag %u ename '%.*s'",
203 tag, fc->params.rerror.error.len,
204 fc->params.rerror.error.str);
205 if (extended)
206 ret += scnprintf(buf+ret, buflen-ret, " ecode %d\n",
207 fc->params.rerror.errno);
208 break;
209
210 case TFLUSH:
211 ret += scnprintf(buf+ret, buflen-ret, "Tflush tag %u oldtag %u",
212 tag, fc->params.tflush.oldtag);
213 break;
214
215 case RFLUSH:
216 ret += scnprintf(buf+ret, buflen-ret, "Rflush tag %u", tag);
217 break;
218
219 case TWALK:
220 ret += scnprintf(buf+ret, buflen-ret,
221 "Twalk tag %u fid %d newfid %d nwname %d", tag,
222 fc->params.twalk.fid, fc->params.twalk.newfid,
223 fc->params.twalk.nwname);
224 for(i = 0; i < fc->params.twalk.nwname; i++)
225 ret += scnprintf(buf+ret, buflen-ret," '%.*s'",
226 fc->params.twalk.wnames[i].len,
227 fc->params.twalk.wnames[i].str);
228 break;
229
230 case RWALK:
231 ret += scnprintf(buf+ret, buflen-ret, "Rwalk tag %u nwqid %d",
232 tag, fc->params.rwalk.nwqid);
233 for(i = 0; i < fc->params.rwalk.nwqid; i++)
234 ret += v9fs_printqid(buf+ret, buflen-ret,
235 &fc->params.rwalk.wqids[i]);
236 break;
237
238 case TOPEN:
239 ret += scnprintf(buf+ret, buflen-ret,
240 "Topen tag %u fid %d mode %d", tag,
241 fc->params.topen.fid, fc->params.topen.mode);
242 break;
243
244 case ROPEN:
245 ret += scnprintf(buf+ret, buflen-ret, "Ropen tag %u", tag);
246 ret += v9fs_printqid(buf+ret, buflen-ret, &fc->params.ropen.qid);
247 ret += scnprintf(buf+ret, buflen-ret," iounit %d",
248 fc->params.ropen.iounit);
249 break;
250
251 case TCREATE:
252 ret += scnprintf(buf+ret, buflen-ret,
253 "Tcreate tag %u fid %d name '%.*s' perm ", tag,
254 fc->params.tcreate.fid, fc->params.tcreate.name.len,
255 fc->params.tcreate.name.str);
256
257 ret += v9fs_printperm(buf+ret, buflen-ret, fc->params.tcreate.perm);
258 ret += scnprintf(buf+ret, buflen-ret, " mode %d",
259 fc->params.tcreate.mode);
260 break;
261
262 case RCREATE:
263 ret += scnprintf(buf+ret, buflen-ret, "Rcreate tag %u", tag);
264 ret += v9fs_printqid(buf+ret, buflen-ret, &fc->params.rcreate.qid);
265 ret += scnprintf(buf+ret, buflen-ret, " iounit %d",
266 fc->params.rcreate.iounit);
267 break;
268
269 case TREAD:
270 ret += scnprintf(buf+ret, buflen-ret,
271 "Tread tag %u fid %d offset %lld count %u", tag,
272 fc->params.tread.fid,
273 (long long int) fc->params.tread.offset,
274 fc->params.tread.count);
275 break;
276
277 case RREAD:
278 ret += scnprintf(buf+ret, buflen-ret,
279 "Rread tag %u count %u data ", tag,
280 fc->params.rread.count);
281 ret += v9fs_printdata(buf+ret, buflen-ret, fc->params.rread.data,
282 fc->params.rread.count);
283 break;
284
285 case TWRITE:
286 ret += scnprintf(buf+ret, buflen-ret,
287 "Twrite tag %u fid %d offset %lld count %u data ",
288 tag, fc->params.twrite.fid,
289 (long long int) fc->params.twrite.offset,
290 fc->params.twrite.count);
291 ret += v9fs_printdata(buf+ret, buflen-ret, fc->params.twrite.data,
292 fc->params.twrite.count);
293 break;
294
295 case RWRITE:
296 ret += scnprintf(buf+ret, buflen-ret, "Rwrite tag %u count %u",
297 tag, fc->params.rwrite.count);
298 break;
299
300 case TCLUNK:
301 ret += scnprintf(buf+ret, buflen-ret, "Tclunk tag %u fid %d",
302 tag, fc->params.tclunk.fid);
303 break;
304
305 case RCLUNK:
306 ret += scnprintf(buf+ret, buflen-ret, "Rclunk tag %u", tag);
307 break;
308
309 case TREMOVE:
310 ret += scnprintf(buf+ret, buflen-ret, "Tremove tag %u fid %d",
311 tag, fc->params.tremove.fid);
312 break;
313
314 case RREMOVE:
315 ret += scnprintf(buf+ret, buflen-ret, "Rremove tag %u", tag);
316 break;
317
318 case TSTAT:
319 ret += scnprintf(buf+ret, buflen-ret, "Tstat tag %u fid %d",
320 tag, fc->params.tstat.fid);
321 break;
322
323 case RSTAT:
324 ret += scnprintf(buf+ret, buflen-ret, "Rstat tag %u ", tag);
325 ret += v9fs_printstat(buf+ret, buflen-ret, &fc->params.rstat.stat,
326 extended);
327 break;
328
329 case TWSTAT:
330 ret += scnprintf(buf+ret, buflen-ret, "Twstat tag %u fid %d ",
331 tag, fc->params.twstat.fid);
332 ret += v9fs_printstat(buf+ret, buflen-ret, &fc->params.twstat.stat,
333 extended);
334 break;
335
336 case RWSTAT:
337 ret += scnprintf(buf+ret, buflen-ret, "Rwstat tag %u", tag);
338 break;
339
340 default:
341 ret += scnprintf(buf+ret, buflen-ret, "unknown type %d", type);
342 break;
343 }
344
345 return ret;
346}
diff --git a/fs/9p/fid.c b/fs/9p/fid.c
index c4d13bf904d2..b7608af07ce8 100644
--- a/fs/9p/fid.c
+++ b/fs/9p/fid.c
@@ -4,9 +4,8 @@
4 * Copyright (C) 2005, 2006 by Eric Van Hensbergen <ericvh@gmail.com> 4 * Copyright (C) 2005, 2006 by Eric Van Hensbergen <ericvh@gmail.com>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License version 2
8 * the Free Software Foundation; either version 2 of the License, or 8 * as published by the Free Software Foundation.
9 * (at your option) any later version.
10 * 9 *
11 * This program is distributed in the hope that it will be useful, 10 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/fs/9p/fid.h b/fs/9p/fid.h
index 1fc2dd08d75a..aa974d6875c3 100644
--- a/fs/9p/fid.h
+++ b/fs/9p/fid.h
@@ -4,9 +4,8 @@
4 * Copyright (C) 2005 by Eric Van Hensbergen <ericvh@gmail.com> 4 * Copyright (C) 2005 by Eric Van Hensbergen <ericvh@gmail.com>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License version 2
8 * the Free Software Foundation; either version 2 of the License, or 8 * as published by the Free Software Foundation.
9 * (at your option) any later version.
10 * 9 *
11 * This program is distributed in the hope that it will be useful, 10 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/fs/9p/mux.c b/fs/9p/mux.c
index e2ae60adda99..3e5b124a7212 100644
--- a/fs/9p/mux.c
+++ b/fs/9p/mux.c
@@ -7,9 +7,8 @@
7 * Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net> 7 * Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License version 2
11 * the Free Software Foundation; either version 2 of the License, or 11 * as published by the Free Software Foundation.
12 * (at your option) any later version.
13 * 12 *
14 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -70,7 +69,7 @@ struct v9fs_mux_data {
70 int msize; 69 int msize;
71 unsigned char *extended; 70 unsigned char *extended;
72 struct v9fs_transport *trans; 71 struct v9fs_transport *trans;
73 struct v9fs_idpool tidpool; 72 struct v9fs_idpool tagpool;
74 int err; 73 int err;
75 wait_queue_head_t equeue; 74 wait_queue_head_t equeue;
76 struct list_head req_list; 75 struct list_head req_list;
@@ -280,8 +279,8 @@ struct v9fs_mux_data *v9fs_mux_init(struct v9fs_transport *trans, int msize,
280 m->msize = msize; 279 m->msize = msize;
281 m->extended = extended; 280 m->extended = extended;
282 m->trans = trans; 281 m->trans = trans;
283 idr_init(&m->tidpool.pool); 282 idr_init(&m->tagpool.pool);
284 init_MUTEX(&m->tidpool.lock); 283 init_MUTEX(&m->tagpool.lock);
285 m->err = 0; 284 m->err = 0;
286 init_waitqueue_head(&m->equeue); 285 init_waitqueue_head(&m->equeue);
287 INIT_LIST_HEAD(&m->req_list); 286 INIT_LIST_HEAD(&m->req_list);
@@ -635,6 +634,14 @@ static void v9fs_read_work(void *a)
635 goto error; 634 goto error;
636 } 635 }
637 636
637 if ((v9fs_debug_level&DEBUG_FCALL) == DEBUG_FCALL) {
638 char buf[150];
639
640 v9fs_printfcall(buf, sizeof(buf), m->rcall,
641 *m->extended);
642 printk(KERN_NOTICE ">>> %p %s\n", m, buf);
643 }
644
638 rcall = m->rcall; 645 rcall = m->rcall;
639 rbuf = m->rbuf; 646 rbuf = m->rbuf;
640 if (m->rpos > n) { 647 if (m->rpos > n) {
@@ -740,6 +747,13 @@ static struct v9fs_req *v9fs_send_request(struct v9fs_mux_data *m,
740 747
741 v9fs_set_tag(tc, n); 748 v9fs_set_tag(tc, n);
742 749
750 if ((v9fs_debug_level&DEBUG_FCALL) == DEBUG_FCALL) {
751 char buf[150];
752
753 v9fs_printfcall(buf, sizeof(buf), tc, *m->extended);
754 printk(KERN_NOTICE "<<< %p %s\n", m, buf);
755 }
756
743 req->tag = n; 757 req->tag = n;
744 req->tcall = tc; 758 req->tcall = tc;
745 req->rcall = NULL; 759 req->rcall = NULL;
@@ -965,7 +979,7 @@ static u16 v9fs_mux_get_tag(struct v9fs_mux_data *m)
965{ 979{
966 int tag; 980 int tag;
967 981
968 tag = v9fs_get_idpool(&m->tidpool); 982 tag = v9fs_get_idpool(&m->tagpool);
969 if (tag < 0) 983 if (tag < 0)
970 return V9FS_NOTAG; 984 return V9FS_NOTAG;
971 else 985 else
@@ -974,6 +988,6 @@ static u16 v9fs_mux_get_tag(struct v9fs_mux_data *m)
974 988
975static void v9fs_mux_put_tag(struct v9fs_mux_data *m, u16 tag) 989static void v9fs_mux_put_tag(struct v9fs_mux_data *m, u16 tag)
976{ 990{
977 if (tag != V9FS_NOTAG && v9fs_check_idpool(tag, &m->tidpool)) 991 if (tag != V9FS_NOTAG && v9fs_check_idpool(tag, &m->tagpool))
978 v9fs_put_idpool(tag, &m->tidpool); 992 v9fs_put_idpool(tag, &m->tagpool);
979} 993}
diff --git a/fs/9p/mux.h b/fs/9p/mux.h
index 17144fdfa11b..e90bfd32ea42 100644
--- a/fs/9p/mux.h
+++ b/fs/9p/mux.h
@@ -7,9 +7,8 @@
7 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> 7 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License version 2
11 * the Free Software Foundation; either version 2 of the License, or 11 * as published by the Free Software Foundation.
12 * (at your option) any later version.
13 * 12 *
14 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/fs/9p/trans_fd.c b/fs/9p/trans_fd.c
index 5b2ce21b10fa..94e0a7fd9fc2 100644
--- a/fs/9p/trans_fd.c
+++ b/fs/9p/trans_fd.c
@@ -1,15 +1,16 @@
1/* 1/*
2 * linux/fs/9p/trans_fd.c 2 * linux/fs/9p/trans_fd.c
3 * 3 *
4 * File Descriptor Transport Layer 4 * Fd transport layer. Includes deprecated socket layer.
5 * 5 *
6 * Copyright (C) 2005 by Latchesar Ionkov <lucho@ionkov.net> 6 * Copyright (C) 2006 by Russ Cox <rsc@swtch.com>
7 * Copyright (C) 2005 by Eric Van Hensbergen <ericvh@gmail.com> 7 * Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net>
8 * Copyright (C) 2004-2005 by Eric Van Hensbergen <ericvh@gmail.com>
9 * Copyright (C) 1997-2002 by Ron Minnich <rminnich@sarnoff.com>
8 * 10 *
9 * This program is free software; you can redistribute it and/or modify 11 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 12 * it under the terms of the GNU General Public License version 2
11 * the Free Software Foundation; either version 2 of the License, or 13 * as published by the Free Software Foundation.
12 * (at your option) any later version.
13 * 14 *
14 * This program is distributed in the hope that it will be useful, 15 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -25,6 +26,7 @@
25 */ 26 */
26 27
27#include <linux/config.h> 28#include <linux/config.h>
29#include <linux/in.h>
28#include <linux/module.h> 30#include <linux/module.h>
29#include <linux/net.h> 31#include <linux/net.h>
30#include <linux/ipv6.h> 32#include <linux/ipv6.h>
@@ -40,89 +42,119 @@
40#include "v9fs.h" 42#include "v9fs.h"
41#include "transport.h" 43#include "transport.h"
42 44
45#define V9FS_PORT 564
46
43struct v9fs_trans_fd { 47struct v9fs_trans_fd {
44 struct file *in_file; 48 struct file *rd;
45 struct file *out_file; 49 struct file *wr;
46}; 50};
47 51
48/** 52/**
49 * v9fs_fd_recv - receive from a socket 53 * v9fs_fd_read- read from a fd
50 * @v9ses: session information 54 * @v9ses: session information
51 * @v: buffer to receive data into 55 * @v: buffer to receive data into
52 * @len: size of receive buffer 56 * @len: size of receive buffer
53 * 57 *
54 */ 58 */
55 59static int v9fs_fd_read(struct v9fs_transport *trans, void *v, int len)
56static int v9fs_fd_recv(struct v9fs_transport *trans, void *v, int len)
57{ 60{
58 struct v9fs_trans_fd *ts = trans ? trans->priv : NULL; 61 int ret;
62 struct v9fs_trans_fd *ts;
59 63
60 if (!trans || trans->status != Connected || !ts) 64 if (!trans || trans->status == Disconnected || !(ts = trans->priv))
61 return -EIO; 65 return -EREMOTEIO;
62 66
63 return kernel_read(ts->in_file, ts->in_file->f_pos, v, len); 67 if (!(ts->rd->f_flags & O_NONBLOCK))
68 dprintk(DEBUG_ERROR, "blocking read ...\n");
69
70 ret = kernel_read(ts->rd, ts->rd->f_pos, v, len);
71 if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN)
72 trans->status = Disconnected;
73 return ret;
64} 74}
65 75
66/** 76/**
67 * v9fs_fd_send - send to a socket 77 * v9fs_fd_write - write to a socket
68 * @v9ses: session information 78 * @v9ses: session information
69 * @v: buffer to send data from 79 * @v: buffer to send data from
70 * @len: size of send buffer 80 * @len: size of send buffer
71 * 81 *
72 */ 82 */
73 83static int v9fs_fd_write(struct v9fs_transport *trans, void *v, int len)
74static int v9fs_fd_send(struct v9fs_transport *trans, void *v, int len)
75{ 84{
76 struct v9fs_trans_fd *ts = trans ? trans->priv : NULL; 85 int ret;
77 mm_segment_t oldfs = get_fs(); 86 mm_segment_t oldfs;
78 int ret = 0; 87 struct v9fs_trans_fd *ts;
79 88
80 if (!trans || trans->status != Connected || !ts) 89 if (!trans || trans->status == Disconnected || !(ts = trans->priv))
81 return -EIO; 90 return -EREMOTEIO;
91
92 if (!(ts->wr->f_flags & O_NONBLOCK))
93 dprintk(DEBUG_ERROR, "blocking write ...\n");
82 94
83 oldfs = get_fs(); 95 oldfs = get_fs();
84 set_fs(get_ds()); 96 set_fs(get_ds());
85 /* The cast to a user pointer is valid due to the set_fs() */ 97 /* The cast to a user pointer is valid due to the set_fs() */
86 ret = vfs_write(ts->out_file, (void __user *)v, len, &ts->out_file->f_pos); 98 ret = vfs_write(ts->wr, (void __user *)v, len, &ts->wr->f_pos);
87 set_fs(oldfs); 99 set_fs(oldfs);
88 100
101 if (ret <= 0 && ret != -ERESTARTSYS && ret != -EAGAIN)
102 trans->status = Disconnected;
89 return ret; 103 return ret;
90} 104}
91 105
92/** 106static unsigned int
93 * v9fs_fd_init - initialize file descriptor transport 107v9fs_fd_poll(struct v9fs_transport *trans, struct poll_table_struct *pt)
94 * @v9ses: session information
95 * @addr: address of server to mount
96 * @data: mount options
97 *
98 */
99
100static int
101v9fs_fd_init(struct v9fs_session_info *v9ses, const char *addr, char *data)
102{ 108{
103 struct v9fs_trans_fd *ts = NULL; 109 int ret, n;
104 struct v9fs_transport *trans = v9ses->transport; 110 struct v9fs_trans_fd *ts;
111 mm_segment_t oldfs;
105 112
106 if((v9ses->wfdno == ~0) || (v9ses->rfdno == ~0)) { 113 if (!trans || trans->status != Connected || !(ts = trans->priv))
107 printk(KERN_ERR "v9fs: Insufficient options for proto=fd\n"); 114 return -EREMOTEIO;
108 return -ENOPROTOOPT;
109 }
110 115
111 ts = kmalloc(sizeof(struct v9fs_trans_fd), GFP_KERNEL); 116 if (!ts->rd->f_op || !ts->rd->f_op->poll)
117 return -EIO;
112 118
113 if (!ts) 119 if (!ts->wr->f_op || !ts->wr->f_op->poll)
114 return -ENOMEM; 120 return -EIO;
115 121
116 ts->in_file = fget( v9ses->rfdno ); 122 oldfs = get_fs();
117 ts->out_file = fget( v9ses->wfdno ); 123 set_fs(get_ds());
118 124
119 if (!ts->in_file || !ts->out_file) { 125 ret = ts->rd->f_op->poll(ts->rd, pt);
120 if (ts->in_file) 126 if (ret < 0)
121 fput(ts->in_file); 127 goto end;
122 128
123 if (ts->out_file) 129 if (ts->rd != ts->wr) {
124 fput(ts->out_file); 130 n = ts->wr->f_op->poll(ts->wr, pt);
131 if (n < 0) {
132 ret = n;
133 goto end;
134 }
135 ret = (ret & ~POLLOUT) | (n & ~POLLIN);
136 }
125 137
138 end:
139 set_fs(oldfs);
140 return ret;
141}
142
143static int v9fs_fd_open(struct v9fs_session_info *v9ses, int rfd, int wfd)
144{
145 struct v9fs_transport *trans = v9ses->transport;
146 struct v9fs_trans_fd *ts = kmalloc(sizeof(struct v9fs_trans_fd),
147 GFP_KERNEL);
148 if (!ts)
149 return -ENOMEM;
150
151 ts->rd = fget(rfd);
152 ts->wr = fget(wfd);
153 if (!ts->rd || !ts->wr) {
154 if (ts->rd)
155 fput(ts->rd);
156 if (ts->wr)
157 fput(ts->wr);
126 kfree(ts); 158 kfree(ts);
127 return -EIO; 159 return -EIO;
128 } 160 }
@@ -133,84 +165,145 @@ v9fs_fd_init(struct v9fs_session_info *v9ses, const char *addr, char *data)
133 return 0; 165 return 0;
134} 166}
135 167
136 168static int v9fs_fd_init(struct v9fs_session_info *v9ses, const char *addr,
137/** 169 char *data)
138 * v9fs_fd_close - shutdown file descriptor
139 * @trans: private socket structure
140 *
141 */
142
143static void v9fs_fd_close(struct v9fs_transport *trans)
144{ 170{
145 struct v9fs_trans_fd *ts; 171 if (v9ses->rfdno == ~0 || v9ses->wfdno == ~0) {
146 172 printk(KERN_ERR "v9fs: Insufficient options for proto=fd\n");
147 if (!trans) 173 return -ENOPROTOOPT;
148 return; 174 }
149
150 ts = xchg(&trans->priv, NULL);
151 175
152 if (!ts) 176 return v9fs_fd_open(v9ses, v9ses->rfdno, v9ses->wfdno);
153 return; 177}
154 178
155 trans->status = Disconnected; 179static int v9fs_socket_open(struct v9fs_session_info *v9ses,
156 if (ts->in_file) 180 struct socket *csocket)
157 fput(ts->in_file); 181{
182 int fd, ret;
183
184 csocket->sk->sk_allocation = GFP_NOIO;
185 if ((fd = sock_map_fd(csocket)) < 0) {
186 eprintk(KERN_ERR, "v9fs_socket_open: failed to map fd\n");
187 ret = fd;
188 release_csocket:
189 sock_release(csocket);
190 return ret;
191 }
158 192
159 if (ts->out_file) 193 if ((ret = v9fs_fd_open(v9ses, fd, fd)) < 0) {
160 fput(ts->out_file); 194 sockfd_put(csocket);
195 eprintk(KERN_ERR, "v9fs_socket_open: failed to open fd\n");
196 goto release_csocket;
197 }
161 198
162 kfree(ts); 199 ((struct v9fs_trans_fd *)v9ses->transport->priv)->rd->f_flags |=
200 O_NONBLOCK;
201 return 0;
163} 202}
164 203
165static unsigned int 204static int v9fs_tcp_init(struct v9fs_session_info *v9ses, const char *addr,
166v9fs_fd_poll(struct v9fs_transport *trans, struct poll_table_struct *pt) 205 char *data)
167{ 206{
168 int ret, n; 207 int ret;
169 struct v9fs_trans_fd *ts; 208 struct socket *csocket = NULL;
170 mm_segment_t oldfs; 209 struct sockaddr_in sin_server;
210
211 sin_server.sin_family = AF_INET;
212 sin_server.sin_addr.s_addr = in_aton(addr);
213 sin_server.sin_port = htons(v9ses->port);
214 sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket);
215
216 if (!csocket) {
217 eprintk(KERN_ERR, "v9fs_trans_tcp: problem creating socket\n");
218 return -1;
219 }
171 220
172 if (!trans) 221 ret = csocket->ops->connect(csocket,
173 return -EIO; 222 (struct sockaddr *)&sin_server,
223 sizeof(struct sockaddr_in), 0);
224 if (ret < 0) {
225 eprintk(KERN_ERR,
226 "v9fs_trans_tcp: problem connecting socket to %s\n",
227 addr);
228 return ret;
229 }
174 230
175 ts = trans->priv; 231 return v9fs_socket_open(v9ses, csocket);
176 if (trans->status != Connected || !ts) 232}
177 return -EIO;
178 233
179 oldfs = get_fs(); 234static int
180 set_fs(get_ds()); 235v9fs_unix_init(struct v9fs_session_info *v9ses, const char *addr, char *data)
236{
237 int ret;
238 struct socket *csocket;
239 struct sockaddr_un sun_server;
240
241 if (strlen(addr) > UNIX_PATH_MAX) {
242 eprintk(KERN_ERR, "v9fs_trans_unix: address too long: %s\n",
243 addr);
244 return -ENAMETOOLONG;
245 }
181 246
182 if (!ts->in_file->f_op || !ts->in_file->f_op->poll) { 247 sun_server.sun_family = PF_UNIX;
183 ret = -EIO; 248 strcpy(sun_server.sun_path, addr);
184 goto end; 249 sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket);
250 ret = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server,
251 sizeof(struct sockaddr_un) - 1, 0);
252 if (ret < 0) {
253 eprintk(KERN_ERR,
254 "v9fs_trans_unix: problem connecting socket: %s: %d\n",
255 addr, ret);
256 return ret;
185 } 257 }
186 258
187 ret = ts->in_file->f_op->poll(ts->in_file, pt); 259 return v9fs_socket_open(v9ses, csocket);
260}
188 261
189 if (ts->out_file != ts->in_file) { 262/**
190 if (!ts->out_file->f_op || !ts->out_file->f_op->poll) { 263 * v9fs_sock_close - shutdown socket
191 ret = -EIO; 264 * @trans: private socket structure
192 goto end; 265 *
193 } 266 */
267static void v9fs_fd_close(struct v9fs_transport *trans)
268{
269 struct v9fs_trans_fd *ts;
194 270
195 n = ts->out_file->f_op->poll(ts->out_file, pt); 271 if (!trans)
272 return;
196 273
197 ret &= ~POLLOUT; 274 ts = xchg(&trans->priv, NULL);
198 n &= ~POLLIN;
199 275
200 ret |= n; 276 if (!ts)
201 } 277 return;
202 278
203end: 279 trans->status = Disconnected;
204 set_fs(oldfs); 280 if (ts->rd)
205 return ret; 281 fput(ts->rd);
282 if (ts->wr)
283 fput(ts->wr);
284 kfree(ts);
206} 285}
207 286
208
209struct v9fs_transport v9fs_trans_fd = { 287struct v9fs_transport v9fs_trans_fd = {
210 .init = v9fs_fd_init, 288 .init = v9fs_fd_init,
211 .write = v9fs_fd_send, 289 .write = v9fs_fd_write,
212 .read = v9fs_fd_recv, 290 .read = v9fs_fd_read,
213 .close = v9fs_fd_close, 291 .close = v9fs_fd_close,
214 .poll = v9fs_fd_poll, 292 .poll = v9fs_fd_poll,
215}; 293};
216 294
295struct v9fs_transport v9fs_trans_tcp = {
296 .init = v9fs_tcp_init,
297 .write = v9fs_fd_write,
298 .read = v9fs_fd_read,
299 .close = v9fs_fd_close,
300 .poll = v9fs_fd_poll,
301};
302
303struct v9fs_transport v9fs_trans_unix = {
304 .init = v9fs_unix_init,
305 .write = v9fs_fd_write,
306 .read = v9fs_fd_read,
307 .close = v9fs_fd_close,
308 .poll = v9fs_fd_poll,
309};
diff --git a/fs/9p/trans_sock.c b/fs/9p/trans_sock.c
deleted file mode 100644
index 44e830697acb..000000000000
--- a/fs/9p/trans_sock.c
+++ /dev/null
@@ -1,334 +0,0 @@
1/*
2 * linux/fs/9p/trans_socket.c
3 *
4 * Socket Transport Layer
5 *
6 * Copyright (C) 2004-2005 by Latchesar Ionkov <lucho@ionkov.net>
7 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
8 * Copyright (C) 1997-2002 by Ron Minnich <rminnich@sarnoff.com>
9 * Copyright (C) 1995, 1996 by Olaf Kirch <okir@monad.swb.de>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to:
23 * Free Software Foundation
24 * 51 Franklin Street, Fifth Floor
25 * Boston, MA 02111-1301 USA
26 *
27 */
28
29#include <linux/config.h>
30#include <linux/in.h>
31#include <linux/module.h>
32#include <linux/net.h>
33#include <linux/ipv6.h>
34#include <linux/errno.h>
35#include <linux/kernel.h>
36#include <linux/un.h>
37#include <asm/uaccess.h>
38#include <linux/inet.h>
39#include <linux/idr.h>
40#include <linux/file.h>
41
42#include "debug.h"
43#include "v9fs.h"
44#include "transport.h"
45
46#define V9FS_PORT 564
47
48struct v9fs_trans_sock {
49 struct socket *s;
50 struct file *filp;
51};
52
53/**
54 * v9fs_sock_recv - receive from a socket
55 * @v9ses: session information
56 * @v: buffer to receive data into
57 * @len: size of receive buffer
58 *
59 */
60
61static int v9fs_sock_recv(struct v9fs_transport *trans, void *v, int len)
62{
63 int ret;
64 struct v9fs_trans_sock *ts;
65
66 if (!trans || trans->status == Disconnected) {
67 dprintk(DEBUG_ERROR, "disconnected ...\n");
68 return -EREMOTEIO;
69 }
70
71 ts = trans->priv;
72
73 if (!(ts->filp->f_flags & O_NONBLOCK))
74 dprintk(DEBUG_ERROR, "blocking read ...\n");
75
76 ret = kernel_read(ts->filp, ts->filp->f_pos, v, len);
77 if (ret <= 0) {
78 if (ret != -ERESTARTSYS && ret != -EAGAIN)
79 trans->status = Disconnected;
80 }
81
82 return ret;
83}
84
85/**
86 * v9fs_sock_send - send to a socket
87 * @v9ses: session information
88 * @v: buffer to send data from
89 * @len: size of send buffer
90 *
91 */
92
93static int v9fs_sock_send(struct v9fs_transport *trans, void *v, int len)
94{
95 int ret;
96 mm_segment_t oldfs;
97 struct v9fs_trans_sock *ts;
98
99 if (!trans || trans->status == Disconnected) {
100 dprintk(DEBUG_ERROR, "disconnected ...\n");
101 return -EREMOTEIO;
102 }
103
104 ts = trans->priv;
105 if (!ts) {
106 dprintk(DEBUG_ERROR, "no transport ...\n");
107 return -EREMOTEIO;
108 }
109
110 if (!(ts->filp->f_flags & O_NONBLOCK))
111 dprintk(DEBUG_ERROR, "blocking write ...\n");
112
113 oldfs = get_fs();
114 set_fs(get_ds());
115 ret = vfs_write(ts->filp, (void __user *)v, len, &ts->filp->f_pos);
116 set_fs(oldfs);
117
118 if (ret < 0) {
119 if (ret != -ERESTARTSYS)
120 trans->status = Disconnected;
121 }
122
123 return ret;
124}
125
126static unsigned int v9fs_sock_poll(struct v9fs_transport *trans,
127 struct poll_table_struct *pt) {
128
129 int ret;
130 struct v9fs_trans_sock *ts;
131 mm_segment_t oldfs;
132
133 if (!trans) {
134 dprintk(DEBUG_ERROR, "no transport\n");
135 return -EIO;
136 }
137
138 ts = trans->priv;
139 if (trans->status != Connected || !ts) {
140 dprintk(DEBUG_ERROR, "transport disconnected: %d\n", trans->status);
141 return -EIO;
142 }
143
144 oldfs = get_fs();
145 set_fs(get_ds());
146
147 if (!ts->filp->f_op || !ts->filp->f_op->poll) {
148 dprintk(DEBUG_ERROR, "no poll operation\n");
149 ret = -EIO;
150 goto end;
151 }
152
153 ret = ts->filp->f_op->poll(ts->filp, pt);
154
155end:
156 set_fs(oldfs);
157 return ret;
158}
159
160
161/**
162 * v9fs_tcp_init - initialize TCP socket
163 * @v9ses: session information
164 * @addr: address of server to mount
165 * @data: mount options
166 *
167 */
168
169static int
170v9fs_tcp_init(struct v9fs_session_info *v9ses, const char *addr, char *data)
171{
172 struct socket *csocket = NULL;
173 struct sockaddr_in sin_server;
174 int rc = 0;
175 struct v9fs_trans_sock *ts = NULL;
176 struct v9fs_transport *trans = v9ses->transport;
177 int fd;
178
179 trans->status = Disconnected;
180
181 ts = kmalloc(sizeof(struct v9fs_trans_sock), GFP_KERNEL);
182
183 if (!ts)
184 return -ENOMEM;
185
186 trans->priv = ts;
187 ts->s = NULL;
188 ts->filp = NULL;
189
190 if (!addr)
191 return -EINVAL;
192
193 dprintk(DEBUG_TRANS, "Connecting to %s\n", addr);
194
195 sin_server.sin_family = AF_INET;
196 sin_server.sin_addr.s_addr = in_aton(addr);
197 sin_server.sin_port = htons(v9ses->port);
198 sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &csocket);
199 rc = csocket->ops->connect(csocket,
200 (struct sockaddr *)&sin_server,
201 sizeof(struct sockaddr_in), 0);
202 if (rc < 0) {
203 eprintk(KERN_ERR,
204 "v9fs_trans_tcp: problem connecting socket to %s\n",
205 addr);
206 return rc;
207 }
208 csocket->sk->sk_allocation = GFP_NOIO;
209
210 fd = sock_map_fd(csocket);
211 if (fd < 0) {
212 sock_release(csocket);
213 kfree(ts);
214 trans->priv = NULL;
215 return fd;
216 }
217
218 ts->s = csocket;
219 ts->filp = fget(fd);
220 ts->filp->f_flags |= O_NONBLOCK;
221 trans->status = Connected;
222
223 return 0;
224}
225
226/**
227 * v9fs_unix_init - initialize UNIX domain socket
228 * @v9ses: session information
229 * @dev_name: path to named pipe
230 * @data: mount options
231 *
232 */
233
234static int
235v9fs_unix_init(struct v9fs_session_info *v9ses, const char *dev_name,
236 char *data)
237{
238 int rc, fd;
239 struct socket *csocket;
240 struct sockaddr_un sun_server;
241 struct v9fs_transport *trans;
242 struct v9fs_trans_sock *ts;
243
244 rc = 0;
245 csocket = NULL;
246 trans = v9ses->transport;
247
248 trans->status = Disconnected;
249
250 if (strlen(dev_name) > UNIX_PATH_MAX) {
251 eprintk(KERN_ERR, "v9fs_trans_unix: address too long: %s\n",
252 dev_name);
253 return -ENOMEM;
254 }
255
256 ts = kmalloc(sizeof(struct v9fs_trans_sock), GFP_KERNEL);
257 if (!ts)
258 return -ENOMEM;
259
260 trans->priv = ts;
261 ts->s = NULL;
262 ts->filp = NULL;
263
264 sun_server.sun_family = PF_UNIX;
265 strcpy(sun_server.sun_path, dev_name);
266 sock_create_kern(PF_UNIX, SOCK_STREAM, 0, &csocket);
267 rc = csocket->ops->connect(csocket, (struct sockaddr *)&sun_server,
268 sizeof(struct sockaddr_un) - 1, 0); /* -1 *is* important */
269 if (rc < 0) {
270 eprintk(KERN_ERR,
271 "v9fs_trans_unix: problem connecting socket: %s: %d\n",
272 dev_name, rc);
273 return rc;
274 }
275 csocket->sk->sk_allocation = GFP_NOIO;
276
277 fd = sock_map_fd(csocket);
278 if (fd < 0) {
279 sock_release(csocket);
280 kfree(ts);
281 trans->priv = NULL;
282 return fd;
283 }
284
285 ts->s = csocket;
286 ts->filp = fget(fd);
287 ts->filp->f_flags |= O_NONBLOCK;
288 trans->status = Connected;
289
290 return 0;
291}
292
293/**
294 * v9fs_sock_close - shutdown socket
295 * @trans: private socket structure
296 *
297 */
298
299static void v9fs_sock_close(struct v9fs_transport *trans)
300{
301 struct v9fs_trans_sock *ts;
302
303 if (!trans)
304 return;
305
306 ts = trans->priv;
307
308 if ((ts) && (ts->filp)) {
309 fput(ts->filp);
310 ts->filp = NULL;
311 ts->s = NULL;
312 trans->status = Disconnected;
313 }
314
315 kfree(ts);
316
317 trans->priv = NULL;
318}
319
320struct v9fs_transport v9fs_trans_tcp = {
321 .init = v9fs_tcp_init,
322 .write = v9fs_sock_send,
323 .read = v9fs_sock_recv,
324 .close = v9fs_sock_close,
325 .poll = v9fs_sock_poll,
326};
327
328struct v9fs_transport v9fs_trans_unix = {
329 .init = v9fs_unix_init,
330 .write = v9fs_sock_send,
331 .read = v9fs_sock_recv,
332 .close = v9fs_sock_close,
333 .poll = v9fs_sock_poll,
334};
diff --git a/fs/9p/transport.h b/fs/9p/transport.h
index 91fcdb94b361..b38a4b8a41ce 100644
--- a/fs/9p/transport.h
+++ b/fs/9p/transport.h
@@ -7,9 +7,8 @@
7 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> 7 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License version 2
11 * the Free Software Foundation; either version 2 of the License, or 11 * as published by the Free Software Foundation.
12 * (at your option) any later version.
13 * 12 *
14 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index 61352491ba36..d37416eb5791 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -7,9 +7,8 @@
7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License version 2
11 * the Free Software Foundation; either version 2 of the License, or 11 * as published by the Free Software Foundation.
12 * (at your option) any later version.
13 * 12 *
14 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -51,7 +50,7 @@ enum {
51 Opt_port, Opt_msize, Opt_uid, Opt_gid, Opt_afid, Opt_debug, 50 Opt_port, Opt_msize, Opt_uid, Opt_gid, Opt_afid, Opt_debug,
52 Opt_rfdno, Opt_wfdno, 51 Opt_rfdno, Opt_wfdno,
53 /* String options */ 52 /* String options */
54 Opt_name, Opt_remotename, 53 Opt_uname, Opt_remotename,
55 /* Options that take no arguments */ 54 /* Options that take no arguments */
56 Opt_legacy, Opt_nodevmap, Opt_unix, Opt_tcp, Opt_fd, 55 Opt_legacy, Opt_nodevmap, Opt_unix, Opt_tcp, Opt_fd,
57 /* Error token */ 56 /* Error token */
@@ -67,7 +66,7 @@ static match_table_t tokens = {
67 {Opt_rfdno, "rfdno=%u"}, 66 {Opt_rfdno, "rfdno=%u"},
68 {Opt_wfdno, "wfdno=%u"}, 67 {Opt_wfdno, "wfdno=%u"},
69 {Opt_debug, "debug=%x"}, 68 {Opt_debug, "debug=%x"},
70 {Opt_name, "name=%s"}, 69 {Opt_uname, "uname=%s"},
71 {Opt_remotename, "aname=%s"}, 70 {Opt_remotename, "aname=%s"},
72 {Opt_unix, "proto=unix"}, 71 {Opt_unix, "proto=unix"},
73 {Opt_tcp, "proto=tcp"}, 72 {Opt_tcp, "proto=tcp"},
@@ -116,7 +115,7 @@ static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses)
116 if (!*p) 115 if (!*p)
117 continue; 116 continue;
118 token = match_token(p, tokens, args); 117 token = match_token(p, tokens, args);
119 if (token < Opt_name) { 118 if (token < Opt_uname) {
120 if ((ret = match_int(&args[0], &option)) < 0) { 119 if ((ret = match_int(&args[0], &option)) < 0) {
121 dprintk(DEBUG_ERROR, 120 dprintk(DEBUG_ERROR,
122 "integer field, but no integer?\n"); 121 "integer field, but no integer?\n");
@@ -158,7 +157,7 @@ static void v9fs_parse_options(char *options, struct v9fs_session_info *v9ses)
158 case Opt_fd: 157 case Opt_fd:
159 v9ses->proto = PROTO_FD; 158 v9ses->proto = PROTO_FD;
160 break; 159 break;
161 case Opt_name: 160 case Opt_uname:
162 match_strcpy(v9ses->name, &args[0]); 161 match_strcpy(v9ses->name, &args[0]);
163 break; 162 break;
164 case Opt_remotename: 163 case Opt_remotename:
@@ -289,7 +288,7 @@ v9fs_session_init(struct v9fs_session_info *v9ses,
289 /* set global debug level */ 288 /* set global debug level */
290 v9fs_debug_level = v9ses->debug; 289 v9fs_debug_level = v9ses->debug;
291 290
292 /* id pools that are session-dependent: FIDs and TIDs */ 291 /* id pools that are session-dependent: fids and tags */
293 idr_init(&v9ses->fidpool.pool); 292 idr_init(&v9ses->fidpool.pool);
294 init_MUTEX(&v9ses->fidpool.lock); 293 init_MUTEX(&v9ses->fidpool.lock);
295 294
diff --git a/fs/9p/v9fs.h b/fs/9p/v9fs.h
index f337da7a0eec..c134d104cb28 100644
--- a/fs/9p/v9fs.h
+++ b/fs/9p/v9fs.h
@@ -5,9 +5,8 @@
5 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 5 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License version 2
9 * the Free Software Foundation; either version 2 of the License, or 9 * as published by the Free Software Foundation.
10 * (at your option) any later version.
11 * 10 *
12 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -91,6 +90,3 @@ void v9fs_session_cancel(struct v9fs_session_info *v9ses);
91#define V9FS_DEFUSER "nobody" 90#define V9FS_DEFUSER "nobody"
92#define V9FS_DEFANAME "" 91#define V9FS_DEFANAME ""
93 92
94/* inital pool sizes for fids and tags */
95#define V9FS_START_FIDS 8192
96#define V9FS_START_TIDS 256
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h
index a759278acaae..43c9f7de0314 100644
--- a/fs/9p/v9fs_vfs.h
+++ b/fs/9p/v9fs_vfs.h
@@ -5,9 +5,8 @@
5 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 5 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License version 2
9 * the Free Software Foundation; either version 2 of the License, or 9 * as published by the Free Software Foundation.
10 * (at your option) any later version.
11 * 10 *
12 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c
index 8100fb5171b7..efda46fb64d9 100644
--- a/fs/9p/vfs_addr.c
+++ b/fs/9p/vfs_addr.c
@@ -7,9 +7,8 @@
7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License version 2
11 * the Free Software Foundation; either version 2 of the License, or 11 * as published by the Free Software Foundation.
12 * (at your option) any later version.
13 * 12 *
14 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/fs/9p/vfs_dentry.c b/fs/9p/vfs_dentry.c
index 12c9cc926b71..062daa6000ab 100644
--- a/fs/9p/vfs_dentry.c
+++ b/fs/9p/vfs_dentry.c
@@ -7,9 +7,8 @@
7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License version 2
11 * the Free Software Foundation; either version 2 of the License, or 11 * as published by the Free Software Foundation.
12 * (at your option) any later version.
13 * 12 *
14 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -51,7 +50,7 @@
51 * 50 *
52 */ 51 */
53 52
54int v9fs_dentry_delete(struct dentry *dentry) 53static int v9fs_dentry_delete(struct dentry *dentry)
55{ 54{
56 dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry); 55 dprintk(DEBUG_VFS, " dentry: %s (%p)\n", dentry->d_iname, dentry);
57 return 1; 56 return 1;
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c
index cd5eeb032d64..766f11f1215c 100644
--- a/fs/9p/vfs_dir.c
+++ b/fs/9p/vfs_dir.c
@@ -7,9 +7,8 @@
7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License version 2
11 * the Free Software Foundation; either version 2 of the License, or 11 * as published by the Free Software Foundation.
12 * (at your option) any later version.
13 * 12 *
14 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index de3a129698da..59e744163407 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -7,9 +7,8 @@
7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License version 2
11 * the Free Software Foundation; either version 2 of the License, or 11 * as published by the Free Software Foundation.
12 * (at your option) any later version.
13 * 12 *
14 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -69,29 +68,30 @@ int v9fs_file_open(struct inode *inode, struct file *file)
69 68
70 fid = v9fs_get_idpool(&v9ses->fidpool); 69 fid = v9fs_get_idpool(&v9ses->fidpool);
71 if (fid < 0) { 70 if (fid < 0) {
72 eprintk(KERN_WARNING, "newfid fails!\n"); 71 eprintk(KERN_WARNING, "newfid fails!\n");
73 return -ENOSPC; 72 return -ENOSPC;
74 } 73 }
75 74
76 err = v9fs_t_walk(v9ses, vfid->fid, fid, NULL, NULL); 75 err = v9fs_t_walk(v9ses, vfid->fid, fid, NULL, NULL);
77 if (err < 0) { 76 if (err < 0) {
78 dprintk(DEBUG_ERROR, "rewalk didn't work\n"); 77 dprintk(DEBUG_ERROR, "rewalk didn't work\n");
79 goto put_fid; 78 goto put_fid;
80 } 79 }
81 80
82 vfid = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL); 81 /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */
83 if (vfid == NULL) { 82 /* translate open mode appropriately */
84 dprintk(DEBUG_ERROR, "out of memory\n");
85 goto clunk_fid;
86 }
87
88 /* TODO: do special things for O_EXCL, O_NOFOLLOW, O_SYNC */
89 /* translate open mode appropriately */
90 omode = v9fs_uflags2omode(file->f_flags); 83 omode = v9fs_uflags2omode(file->f_flags);
91 err = v9fs_t_open(v9ses, fid, omode, &fcall); 84 err = v9fs_t_open(v9ses, fid, omode, &fcall);
92 if (err < 0) { 85 if (err < 0) {
93 PRINT_FCALL_ERROR("open failed", fcall); 86 PRINT_FCALL_ERROR("open failed", fcall);
94 goto destroy_vfid; 87 goto clunk_fid;
88 }
89
90 vfid = kmalloc(sizeof(struct v9fs_fid), GFP_KERNEL);
91 if (vfid == NULL) {
92 dprintk(DEBUG_ERROR, "out of memory\n");
93 err = -ENOMEM;
94 goto clunk_fid;
95 } 95 }
96 96
97 file->private_data = vfid; 97 file->private_data = vfid;
@@ -106,15 +106,12 @@ int v9fs_file_open(struct inode *inode, struct file *file)
106 106
107 return 0; 107 return 0;
108 108
109destroy_vfid:
110 v9fs_fid_destroy(vfid);
111
112clunk_fid: 109clunk_fid:
113 v9fs_t_clunk(v9ses, fid); 110 v9fs_t_clunk(v9ses, fid);
114 111
115put_fid: 112put_fid:
116 v9fs_put_idpool(fid, &v9ses->fidpool); 113 v9fs_put_idpool(fid, &v9ses->fidpool);
117 kfree(fcall); 114 kfree(fcall);
118 115
119 return err; 116 return err;
120} 117}
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 651a9e14d9a9..133db366d306 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -7,9 +7,8 @@
7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
8 * 8 *
9 * This program is free software; you can redistribute it and/or modify 9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by 10 * it under the terms of the GNU General Public License version 2
11 * the Free Software Foundation; either version 2 of the License, or 11 * as published by the Free Software Foundation.
12 * (at your option) any later version.
13 * 12 *
14 * This program is distributed in the hope that it will be useful, 13 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -255,8 +254,8 @@ struct inode *v9fs_get_inode(struct super_block *sb, int mode)
255} 254}
256 255
257static int 256static int
258v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, 257v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, u32 perm,
259 u32 perm, u8 mode, u32 *fidp, struct v9fs_qid *qid, u32 *iounit) 258 u8 mode, char *extension, u32 *fidp, struct v9fs_qid *qid, u32 *iounit)
260{ 259{
261 u32 fid; 260 u32 fid;
262 int err; 261 int err;
@@ -271,14 +270,14 @@ v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name,
271 err = v9fs_t_walk(v9ses, pfid, fid, NULL, &fcall); 270 err = v9fs_t_walk(v9ses, pfid, fid, NULL, &fcall);
272 if (err < 0) { 271 if (err < 0) {
273 PRINT_FCALL_ERROR("clone error", fcall); 272 PRINT_FCALL_ERROR("clone error", fcall);
274 goto error; 273 goto put_fid;
275 } 274 }
276 kfree(fcall); 275 kfree(fcall);
277 276
278 err = v9fs_t_create(v9ses, fid, name, perm, mode, &fcall); 277 err = v9fs_t_create(v9ses, fid, name, perm, mode, extension, &fcall);
279 if (err < 0) { 278 if (err < 0) {
280 PRINT_FCALL_ERROR("create fails", fcall); 279 PRINT_FCALL_ERROR("create fails", fcall);
281 goto error; 280 goto clunk_fid;
282 } 281 }
283 282
284 if (iounit) 283 if (iounit)
@@ -293,7 +292,11 @@ v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name,
293 kfree(fcall); 292 kfree(fcall);
294 return 0; 293 return 0;
295 294
296error: 295clunk_fid:
296 v9fs_t_clunk(v9ses, fid);
297 fid = V9FS_NOFID;
298
299put_fid:
297 if (fid >= 0) 300 if (fid >= 0)
298 v9fs_put_idpool(fid, &v9ses->fidpool); 301 v9fs_put_idpool(fid, &v9ses->fidpool);
299 302
@@ -348,7 +351,7 @@ error:
348 return ERR_PTR(err); 351 return ERR_PTR(err);
349} 352}
350 353
351struct inode * 354static struct inode *
352v9fs_inode_from_fid(struct v9fs_session_info *v9ses, u32 fid, 355v9fs_inode_from_fid(struct v9fs_session_info *v9ses, u32 fid,
353 struct super_block *sb) 356 struct super_block *sb)
354{ 357{
@@ -474,7 +477,7 @@ v9fs_vfs_create(struct inode *dir, struct dentry *dentry, int mode,
474 flags = O_RDWR; 477 flags = O_RDWR;
475 478
476 err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, 479 err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name,
477 perm, v9fs_uflags2omode(flags), &fid, &qid, &iounit); 480 perm, v9fs_uflags2omode(flags), NULL, &fid, &qid, &iounit);
478 481
479 if (err) 482 if (err)
480 goto error; 483 goto error;
@@ -550,7 +553,7 @@ static int v9fs_vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
550 perm = unixmode2p9mode(v9ses, mode | S_IFDIR); 553 perm = unixmode2p9mode(v9ses, mode | S_IFDIR);
551 554
552 err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, 555 err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name,
553 perm, V9FS_OREAD, &fid, NULL, NULL); 556 perm, V9FS_OREAD, NULL, &fid, NULL, NULL);
554 557
555 if (err) { 558 if (err) {
556 dprintk(DEBUG_ERROR, "create error %d\n", err); 559 dprintk(DEBUG_ERROR, "create error %d\n", err);
@@ -1008,11 +1011,13 @@ static int v9fs_readlink(struct dentry *dentry, char *buffer, int buflen)
1008 1011
1009 /* copy extension buffer into buffer */ 1012 /* copy extension buffer into buffer */
1010 if (fcall->params.rstat.stat.extension.len < buflen) 1013 if (fcall->params.rstat.stat.extension.len < buflen)
1011 buflen = fcall->params.rstat.stat.extension.len; 1014 buflen = fcall->params.rstat.stat.extension.len + 1;
1012 1015
1013 memcpy(buffer, fcall->params.rstat.stat.extension.str, buflen - 1); 1016 memmove(buffer, fcall->params.rstat.stat.extension.str, buflen - 1);
1014 buffer[buflen-1] = 0; 1017 buffer[buflen-1] = 0;
1015 1018
1019 dprintk(DEBUG_ERROR, "%s -> %.*s (%s)\n", dentry->d_name.name, fcall->params.rstat.stat.extension.len,
1020 fcall->params.rstat.stat.extension.str, buffer);
1016 retval = buflen; 1021 retval = buflen;
1017 1022
1018 FreeFcall: 1023 FreeFcall:
@@ -1072,7 +1077,7 @@ static void *v9fs_vfs_follow_link(struct dentry *dentry, struct nameidata *nd)
1072 if (!link) 1077 if (!link)
1073 link = ERR_PTR(-ENOMEM); 1078 link = ERR_PTR(-ENOMEM);
1074 else { 1079 else {
1075 len = v9fs_readlink(dentry, link, strlen(link)); 1080 len = v9fs_readlink(dentry, link, PATH_MAX);
1076 1081
1077 if (len < 0) { 1082 if (len < 0) {
1078 __putname(link); 1083 __putname(link);
@@ -1109,10 +1114,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
1109 struct v9fs_session_info *v9ses; 1114 struct v9fs_session_info *v9ses;
1110 struct v9fs_fid *dfid, *vfid; 1115 struct v9fs_fid *dfid, *vfid;
1111 struct inode *inode; 1116 struct inode *inode;
1112 struct v9fs_fcall *fcall;
1113 struct v9fs_wstat wstat;
1114 1117
1115 fcall = NULL;
1116 inode = NULL; 1118 inode = NULL;
1117 vfid = NULL; 1119 vfid = NULL;
1118 v9ses = v9fs_inode2v9ses(dir); 1120 v9ses = v9fs_inode2v9ses(dir);
@@ -1125,7 +1127,7 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
1125 } 1127 }
1126 1128
1127 err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name, 1129 err = v9fs_create(v9ses, dfid->fid, (char *) dentry->d_name.name,
1128 perm, V9FS_OREAD, &fid, NULL, NULL); 1130 perm, V9FS_OREAD, (char *) extension, &fid, NULL, NULL);
1129 1131
1130 if (err) 1132 if (err)
1131 goto error; 1133 goto error;
@@ -1148,23 +1150,11 @@ static int v9fs_vfs_mkspecial(struct inode *dir, struct dentry *dentry,
1148 goto error; 1150 goto error;
1149 } 1151 }
1150 1152
1151 /* issue a Twstat */
1152 v9fs_blank_wstat(&wstat);
1153 wstat.muid = v9ses->name;
1154 wstat.extension = (char *) extension;
1155 err = v9fs_t_wstat(v9ses, vfid->fid, &wstat, &fcall);
1156 if (err < 0) {
1157 PRINT_FCALL_ERROR("wstat error", fcall);
1158 goto error;
1159 }
1160
1161 kfree(fcall);
1162 dentry->d_op = &v9fs_dentry_operations; 1153 dentry->d_op = &v9fs_dentry_operations;
1163 d_instantiate(dentry, inode); 1154 d_instantiate(dentry, inode);
1164 return 0; 1155 return 0;
1165 1156
1166error: 1157error:
1167 kfree(fcall);
1168 if (vfid) 1158 if (vfid)
1169 v9fs_fid_destroy(vfid); 1159 v9fs_fid_destroy(vfid);
1170 1160
@@ -1224,7 +1214,7 @@ v9fs_vfs_link(struct dentry *old_dentry, struct inode *dir,
1224 } 1214 }
1225 1215
1226 name = __getname(); 1216 name = __getname();
1227 sprintf(name, "hardlink(%d)\n", oldfid->fid); 1217 sprintf(name, "%d\n", oldfid->fid);
1228 retval = v9fs_vfs_mkspecial(dir, dentry, V9FS_DMLINK, name); 1218 retval = v9fs_vfs_mkspecial(dir, dentry, V9FS_DMLINK, name);
1229 __putname(name); 1219 __putname(name);
1230 1220
@@ -1253,6 +1243,8 @@ v9fs_vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
1253 return -EINVAL; 1243 return -EINVAL;
1254 1244
1255 name = __getname(); 1245 name = __getname();
1246 if (!name)
1247 return -ENOMEM;
1256 /* build extension */ 1248 /* build extension */
1257 if (S_ISBLK(mode)) 1249 if (S_ISBLK(mode))
1258 sprintf(name, "b %u %u", MAJOR(rdev), MINOR(rdev)); 1250 sprintf(name, "b %u %u", MAJOR(rdev), MINOR(rdev));
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index d05318fa684e..b0a0ae509c00 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -8,9 +8,8 @@
8 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 8 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by 11 * it under the terms of the GNU General Public License version 2
12 * the Free Software Foundation; either version 2 of the License, or 12 * as published by the Free Software Foundation.
13 * (at your option) any later version.
14 * 13 *
15 * This program is distributed in the hope that it will be useful, 14 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -262,7 +261,7 @@ static struct super_operations v9fs_super_ops = {
262}; 261};
263 262
264struct file_system_type v9fs_fs_type = { 263struct file_system_type v9fs_fs_type = {
265 .name = "9P", 264 .name = "9p",
266 .get_sb = v9fs_get_sb, 265 .get_sb = v9fs_get_sb,
267 .kill_sb = v9fs_kill_super, 266 .kill_sb = v9fs_kill_super,
268 .owner = THIS_MODULE, 267 .owner = THIS_MODULE,
diff --git a/fs/aio.c b/fs/aio.c
index aec2b1916d1b..e41e932ba489 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -122,10 +122,9 @@ static int aio_setup_ring(struct kioctx *ctx)
122 info->nr = 0; 122 info->nr = 0;
123 info->ring_pages = info->internal_pages; 123 info->ring_pages = info->internal_pages;
124 if (nr_pages > AIO_RING_PAGES) { 124 if (nr_pages > AIO_RING_PAGES) {
125 info->ring_pages = kmalloc(sizeof(struct page *) * nr_pages, GFP_KERNEL); 125 info->ring_pages = kcalloc(nr_pages, sizeof(struct page *), GFP_KERNEL);
126 if (!info->ring_pages) 126 if (!info->ring_pages)
127 return -ENOMEM; 127 return -ENOMEM;
128 memset(info->ring_pages, 0, sizeof(struct page *) * nr_pages);
129 } 128 }
130 129
131 info->mmap_size = nr_pages * PAGE_SIZE; 130 info->mmap_size = nr_pages * PAGE_SIZE;
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index c2eac2a50bd2..4349113881fb 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1334,7 +1334,7 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
1334 1334
1335 i = p->state ? ffz(~p->state) + 1 : 0; 1335 i = p->state ? ffz(~p->state) + 1 : 0;
1336 psinfo->pr_state = i; 1336 psinfo->pr_state = i;
1337 psinfo->pr_sname = (i < 0 || i > 5) ? '.' : "RSDTZW"[i]; 1337 psinfo->pr_sname = (i > 5) ? '.' : "RSDTZW"[i];
1338 psinfo->pr_zomb = psinfo->pr_sname == 'Z'; 1338 psinfo->pr_zomb = psinfo->pr_sname == 'Z';
1339 psinfo->pr_nice = task_nice(p); 1339 psinfo->pr_nice = task_nice(p);
1340 psinfo->pr_flag = p->flags; 1340 psinfo->pr_flag = p->flags;
@@ -1465,12 +1465,11 @@ static int elf_core_dump(long signr, struct pt_regs * regs, struct file * file)
1465 read_lock(&tasklist_lock); 1465 read_lock(&tasklist_lock);
1466 do_each_thread(g,p) 1466 do_each_thread(g,p)
1467 if (current->mm == p->mm && current != p) { 1467 if (current->mm == p->mm && current != p) {
1468 tmp = kmalloc(sizeof(*tmp), GFP_ATOMIC); 1468 tmp = kzalloc(sizeof(*tmp), GFP_ATOMIC);
1469 if (!tmp) { 1469 if (!tmp) {
1470 read_unlock(&tasklist_lock); 1470 read_unlock(&tasklist_lock);
1471 goto cleanup; 1471 goto cleanup;
1472 } 1472 }
1473 memset(tmp, 0, sizeof(*tmp));
1474 INIT_LIST_HEAD(&tmp->list); 1473 INIT_LIST_HEAD(&tmp->list);
1475 tmp->thread = p; 1474 tmp->thread = p;
1476 list_add(&tmp->list, &thread_list); 1475 list_add(&tmp->list, &thread_list);
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index 108d56bbd0d0..69f44dcdb0b4 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -36,6 +36,7 @@
36#include <linux/personality.h> 36#include <linux/personality.h>
37#include <linux/init.h> 37#include <linux/init.h>
38#include <linux/flat.h> 38#include <linux/flat.h>
39#include <linux/syscalls.h>
39 40
40#include <asm/byteorder.h> 41#include <asm/byteorder.h>
41#include <asm/system.h> 42#include <asm/system.h>
@@ -426,6 +427,8 @@ static int load_flat_file(struct linux_binprm * bprm,
426 int i, rev, relocs = 0; 427 int i, rev, relocs = 0;
427 loff_t fpos; 428 loff_t fpos;
428 unsigned long start_code, end_code; 429 unsigned long start_code, end_code;
430 int ret;
431 int exec_fileno;
429 432
430 hdr = ((struct flat_hdr *) bprm->buf); /* exec-header */ 433 hdr = ((struct flat_hdr *) bprm->buf); /* exec-header */
431 inode = bprm->file->f_dentry->d_inode; 434 inode = bprm->file->f_dentry->d_inode;
@@ -450,7 +453,8 @@ static int load_flat_file(struct linux_binprm * bprm,
450 */ 453 */
451 if (strncmp(hdr->magic, "#!", 2)) 454 if (strncmp(hdr->magic, "#!", 2))
452 printk("BINFMT_FLAT: bad header magic\n"); 455 printk("BINFMT_FLAT: bad header magic\n");
453 return -ENOEXEC; 456 ret = -ENOEXEC;
457 goto err;
454 } 458 }
455 459
456 if (flags & FLAT_FLAG_KTRACE) 460 if (flags & FLAT_FLAG_KTRACE)
@@ -458,14 +462,16 @@ static int load_flat_file(struct linux_binprm * bprm,
458 462
459 if (rev != FLAT_VERSION && rev != OLD_FLAT_VERSION) { 463 if (rev != FLAT_VERSION && rev != OLD_FLAT_VERSION) {
460 printk("BINFMT_FLAT: bad flat file version 0x%x (supported 0x%x and 0x%x)\n", rev, FLAT_VERSION, OLD_FLAT_VERSION); 464 printk("BINFMT_FLAT: bad flat file version 0x%x (supported 0x%x and 0x%x)\n", rev, FLAT_VERSION, OLD_FLAT_VERSION);
461 return -ENOEXEC; 465 ret = -ENOEXEC;
466 goto err;
462 } 467 }
463 468
464 /* Don't allow old format executables to use shared libraries */ 469 /* Don't allow old format executables to use shared libraries */
465 if (rev == OLD_FLAT_VERSION && id != 0) { 470 if (rev == OLD_FLAT_VERSION && id != 0) {
466 printk("BINFMT_FLAT: shared libraries are not available before rev 0x%x\n", 471 printk("BINFMT_FLAT: shared libraries are not available before rev 0x%x\n",
467 (int) FLAT_VERSION); 472 (int) FLAT_VERSION);
468 return -ENOEXEC; 473 ret = -ENOEXEC;
474 goto err;
469 } 475 }
470 476
471 /* 477 /*
@@ -478,7 +484,8 @@ static int load_flat_file(struct linux_binprm * bprm,
478#ifndef CONFIG_BINFMT_ZFLAT 484#ifndef CONFIG_BINFMT_ZFLAT
479 if (flags & (FLAT_FLAG_GZIP|FLAT_FLAG_GZDATA)) { 485 if (flags & (FLAT_FLAG_GZIP|FLAT_FLAG_GZDATA)) {
480 printk("Support for ZFLAT executables is not enabled.\n"); 486 printk("Support for ZFLAT executables is not enabled.\n");
481 return -ENOEXEC; 487 ret = -ENOEXEC;
488 goto err;
482 } 489 }
483#endif 490#endif
484 491
@@ -490,14 +497,27 @@ static int load_flat_file(struct linux_binprm * bprm,
490 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; 497 rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur;
491 if (rlim >= RLIM_INFINITY) 498 if (rlim >= RLIM_INFINITY)
492 rlim = ~0; 499 rlim = ~0;
493 if (data_len + bss_len > rlim) 500 if (data_len + bss_len > rlim) {
494 return -ENOMEM; 501 ret = -ENOMEM;
502 goto err;
503 }
504
505 /* check file descriptor */
506 exec_fileno = get_unused_fd();
507 if (exec_fileno < 0) {
508 ret = -EMFILE;
509 goto err;
510 }
511 get_file(bprm->file);
512 fd_install(exec_fileno, bprm->file);
495 513
496 /* Flush all traces of the currently running executable */ 514 /* Flush all traces of the currently running executable */
497 if (id == 0) { 515 if (id == 0) {
498 result = flush_old_exec(bprm); 516 result = flush_old_exec(bprm);
499 if (result) 517 if (result) {
500 return result; 518 ret = result;
519 goto err_close;
520 }
501 521
502 /* OK, This is the point of no return */ 522 /* OK, This is the point of no return */
503 set_personality(PER_LINUX); 523 set_personality(PER_LINUX);
@@ -527,7 +547,8 @@ static int load_flat_file(struct linux_binprm * bprm,
527 if (!textpos) 547 if (!textpos)
528 textpos = (unsigned long) -ENOMEM; 548 textpos = (unsigned long) -ENOMEM;
529 printk("Unable to mmap process text, errno %d\n", (int)-textpos); 549 printk("Unable to mmap process text, errno %d\n", (int)-textpos);
530 return(textpos); 550 ret = textpos;
551 goto err_close;
531 } 552 }
532 553
533 down_write(&current->mm->mmap_sem); 554 down_write(&current->mm->mmap_sem);
@@ -542,7 +563,8 @@ static int load_flat_file(struct linux_binprm * bprm,
542 printk("Unable to allocate RAM for process data, errno %d\n", 563 printk("Unable to allocate RAM for process data, errno %d\n",
543 (int)-datapos); 564 (int)-datapos);
544 do_munmap(current->mm, textpos, text_len); 565 do_munmap(current->mm, textpos, text_len);
545 return realdatastart; 566 ret = realdatastart;
567 goto err_close;
546 } 568 }
547 datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long); 569 datapos = realdatastart + MAX_SHARED_LIBS * sizeof(unsigned long);
548 570
@@ -564,7 +586,8 @@ static int load_flat_file(struct linux_binprm * bprm,
564 printk("Unable to read data+bss, errno %d\n", (int)-result); 586 printk("Unable to read data+bss, errno %d\n", (int)-result);
565 do_munmap(current->mm, textpos, text_len); 587 do_munmap(current->mm, textpos, text_len);
566 do_munmap(current->mm, realdatastart, data_len + extra); 588 do_munmap(current->mm, realdatastart, data_len + extra);
567 return result; 589 ret = result;
590 goto err_close;
568 } 591 }
569 592
570 reloc = (unsigned long *) (datapos+(ntohl(hdr->reloc_start)-text_len)); 593 reloc = (unsigned long *) (datapos+(ntohl(hdr->reloc_start)-text_len));
@@ -582,7 +605,8 @@ static int load_flat_file(struct linux_binprm * bprm,
582 textpos = (unsigned long) -ENOMEM; 605 textpos = (unsigned long) -ENOMEM;
583 printk("Unable to allocate RAM for process text/data, errno %d\n", 606 printk("Unable to allocate RAM for process text/data, errno %d\n",
584 (int)-textpos); 607 (int)-textpos);
585 return(textpos); 608 ret = textpos;
609 goto err_close;
586 } 610 }
587 611
588 realdatastart = textpos + ntohl(hdr->data_start); 612 realdatastart = textpos + ntohl(hdr->data_start);
@@ -627,7 +651,8 @@ static int load_flat_file(struct linux_binprm * bprm,
627 printk("Unable to read code+data+bss, errno %d\n",(int)-result); 651 printk("Unable to read code+data+bss, errno %d\n",(int)-result);
628 do_munmap(current->mm, textpos, text_len + data_len + extra + 652 do_munmap(current->mm, textpos, text_len + data_len + extra +
629 MAX_SHARED_LIBS * sizeof(unsigned long)); 653 MAX_SHARED_LIBS * sizeof(unsigned long));
630 return result; 654 ret = result;
655 goto err_close;
631 } 656 }
632 } 657 }
633 658
@@ -690,8 +715,10 @@ static int load_flat_file(struct linux_binprm * bprm,
690 unsigned long addr; 715 unsigned long addr;
691 if (*rp) { 716 if (*rp) {
692 addr = calc_reloc(*rp, libinfo, id, 0); 717 addr = calc_reloc(*rp, libinfo, id, 0);
693 if (addr == RELOC_FAILED) 718 if (addr == RELOC_FAILED) {
694 return -ENOEXEC; 719 ret = -ENOEXEC;
720 goto err_close;
721 }
695 *rp = addr; 722 *rp = addr;
696 } 723 }
697 } 724 }
@@ -718,8 +745,10 @@ static int load_flat_file(struct linux_binprm * bprm,
718 relval = ntohl(reloc[i]); 745 relval = ntohl(reloc[i]);
719 addr = flat_get_relocate_addr(relval); 746 addr = flat_get_relocate_addr(relval);
720 rp = (unsigned long *) calc_reloc(addr, libinfo, id, 1); 747 rp = (unsigned long *) calc_reloc(addr, libinfo, id, 1);
721 if (rp == (unsigned long *)RELOC_FAILED) 748 if (rp == (unsigned long *)RELOC_FAILED) {
722 return -ENOEXEC; 749 ret = -ENOEXEC;
750 goto err_close;
751 }
723 752
724 /* Get the pointer's value. */ 753 /* Get the pointer's value. */
725 addr = flat_get_addr_from_rp(rp, relval, flags); 754 addr = flat_get_addr_from_rp(rp, relval, flags);
@@ -731,8 +760,10 @@ static int load_flat_file(struct linux_binprm * bprm,
731 if ((flags & FLAT_FLAG_GOTPIC) == 0) 760 if ((flags & FLAT_FLAG_GOTPIC) == 0)
732 addr = ntohl(addr); 761 addr = ntohl(addr);
733 addr = calc_reloc(addr, libinfo, id, 0); 762 addr = calc_reloc(addr, libinfo, id, 0);
734 if (addr == RELOC_FAILED) 763 if (addr == RELOC_FAILED) {
735 return -ENOEXEC; 764 ret = -ENOEXEC;
765 goto err_close;
766 }
736 767
737 /* Write back the relocated pointer. */ 768 /* Write back the relocated pointer. */
738 flat_put_addr_at_rp(rp, addr, relval); 769 flat_put_addr_at_rp(rp, addr, relval);
@@ -752,6 +783,10 @@ static int load_flat_file(struct linux_binprm * bprm,
752 stack_len); 783 stack_len);
753 784
754 return 0; 785 return 0;
786err_close:
787 sys_close(exec_fileno);
788err:
789 return ret;
755} 790}
756 791
757 792
diff --git a/fs/bio.c b/fs/bio.c
index 0a8c59cb68f5..73e664c01d30 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -636,12 +636,10 @@ static struct bio *__bio_map_user_iov(request_queue_t *q,
636 return ERR_PTR(-ENOMEM); 636 return ERR_PTR(-ENOMEM);
637 637
638 ret = -ENOMEM; 638 ret = -ENOMEM;
639 pages = kmalloc(nr_pages * sizeof(struct page *), GFP_KERNEL); 639 pages = kcalloc(nr_pages, sizeof(struct page *), GFP_KERNEL);
640 if (!pages) 640 if (!pages)
641 goto out; 641 goto out;
642 642
643 memset(pages, 0, nr_pages * sizeof(struct page *));
644
645 for (i = 0; i < iov_count; i++) { 643 for (i = 0; i < iov_count; i++) {
646 unsigned long uaddr = (unsigned long)iov[i].iov_base; 644 unsigned long uaddr = (unsigned long)iov[i].iov_base;
647 unsigned long len = iov[i].iov_len; 645 unsigned long len = iov[i].iov_len;
@@ -1186,12 +1184,11 @@ void bioset_free(struct bio_set *bs)
1186 1184
1187struct bio_set *bioset_create(int bio_pool_size, int bvec_pool_size, int scale) 1185struct bio_set *bioset_create(int bio_pool_size, int bvec_pool_size, int scale)
1188{ 1186{
1189 struct bio_set *bs = kmalloc(sizeof(*bs), GFP_KERNEL); 1187 struct bio_set *bs = kzalloc(sizeof(*bs), GFP_KERNEL);
1190 1188
1191 if (!bs) 1189 if (!bs)
1192 return NULL; 1190 return NULL;
1193 1191
1194 memset(bs, 0, sizeof(*bs));
1195 bs->bio_pool = mempool_create(bio_pool_size, mempool_alloc_slab, 1192 bs->bio_pool = mempool_create(bio_pool_size, mempool_alloc_slab,
1196 mempool_free_slab, bio_slab); 1193 mempool_free_slab, bio_slab);
1197 1194
diff --git a/fs/buffer.c b/fs/buffer.c
index 6d77ce9f54e5..3b3ab5281920 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -160,12 +160,7 @@ int sync_blockdev(struct block_device *bdev)
160} 160}
161EXPORT_SYMBOL(sync_blockdev); 161EXPORT_SYMBOL(sync_blockdev);
162 162
163/* 163static void __fsync_super(struct super_block *sb)
164 * Write out and wait upon all dirty data associated with this
165 * superblock. Filesystem data as well as the underlying block
166 * device. Takes the superblock lock.
167 */
168int fsync_super(struct super_block *sb)
169{ 164{
170 sync_inodes_sb(sb, 0); 165 sync_inodes_sb(sb, 0);
171 DQUOT_SYNC(sb); 166 DQUOT_SYNC(sb);
@@ -177,7 +172,16 @@ int fsync_super(struct super_block *sb)
177 sb->s_op->sync_fs(sb, 1); 172 sb->s_op->sync_fs(sb, 1);
178 sync_blockdev(sb->s_bdev); 173 sync_blockdev(sb->s_bdev);
179 sync_inodes_sb(sb, 1); 174 sync_inodes_sb(sb, 1);
175}
180 176
177/*
178 * Write out and wait upon all dirty data associated with this
179 * superblock. Filesystem data as well as the underlying block
180 * device. Takes the superblock lock.
181 */
182int fsync_super(struct super_block *sb)
183{
184 __fsync_super(sb);
181 return sync_blockdev(sb->s_bdev); 185 return sync_blockdev(sb->s_bdev);
182} 186}
183 187
@@ -216,19 +220,7 @@ struct super_block *freeze_bdev(struct block_device *bdev)
216 sb->s_frozen = SB_FREEZE_WRITE; 220 sb->s_frozen = SB_FREEZE_WRITE;
217 smp_wmb(); 221 smp_wmb();
218 222
219 sync_inodes_sb(sb, 0); 223 __fsync_super(sb);
220 DQUOT_SYNC(sb);
221
222 lock_super(sb);
223 if (sb->s_dirt && sb->s_op->write_super)
224 sb->s_op->write_super(sb);
225 unlock_super(sb);
226
227 if (sb->s_op->sync_fs)
228 sb->s_op->sync_fs(sb, 1);
229
230 sync_blockdev(sb->s_bdev);
231 sync_inodes_sb(sb, 1);
232 224
233 sb->s_frozen = SB_FREEZE_TRANS; 225 sb->s_frozen = SB_FREEZE_TRANS;
234 smp_wmb(); 226 smp_wmb();
diff --git a/fs/char_dev.c b/fs/char_dev.c
index 5c36345c9bf7..8c6eb04d31e2 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -146,12 +146,10 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor,
146 int ret = 0; 146 int ret = 0;
147 int i; 147 int i;
148 148
149 cd = kmalloc(sizeof(struct char_device_struct), GFP_KERNEL); 149 cd = kzalloc(sizeof(struct char_device_struct), GFP_KERNEL);
150 if (cd == NULL) 150 if (cd == NULL)
151 return ERR_PTR(-ENOMEM); 151 return ERR_PTR(-ENOMEM);
152 152
153 memset(cd, 0, sizeof(struct char_device_struct));
154
155 mutex_lock(&chrdevs_lock); 153 mutex_lock(&chrdevs_lock);
156 154
157 /* temporary */ 155 /* temporary */
@@ -466,9 +464,8 @@ static struct kobj_type ktype_cdev_dynamic = {
466 464
467struct cdev *cdev_alloc(void) 465struct cdev *cdev_alloc(void)
468{ 466{
469 struct cdev *p = kmalloc(sizeof(struct cdev), GFP_KERNEL); 467 struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL);
470 if (p) { 468 if (p) {
471 memset(p, 0, sizeof(struct cdev));
472 p->kobj.ktype = &ktype_cdev_dynamic; 469 p->kobj.ktype = &ktype_cdev_dynamic;
473 INIT_LIST_HEAD(&p->list); 470 INIT_LIST_HEAD(&p->list);
474 kobject_init(&p->kobj); 471 kobject_init(&p->kobj);
diff --git a/fs/compat.c b/fs/compat.c
index 2a88477330fc..ef5a0771592d 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1476,10 +1476,9 @@ int compat_do_execve(char * filename,
1476 int i; 1476 int i;
1477 1477
1478 retval = -ENOMEM; 1478 retval = -ENOMEM;
1479 bprm = kmalloc(sizeof(*bprm), GFP_KERNEL); 1479 bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
1480 if (!bprm) 1480 if (!bprm)
1481 goto out_ret; 1481 goto out_ret;
1482 memset(bprm, 0, sizeof(*bprm));
1483 1482
1484 file = open_exec(filename); 1483 file = open_exec(filename);
1485 retval = PTR_ERR(file); 1484 retval = PTR_ERR(file);
@@ -2170,9 +2169,12 @@ asmlinkage long compat_sys_nfsservctl(int cmd, struct compat_nfsctl_arg __user *
2170 2169
2171 default: 2170 default:
2172 err = -EINVAL; 2171 err = -EINVAL;
2173 goto done; 2172 break;
2174 } 2173 }
2175 2174
2175 if (err)
2176 goto done;
2177
2176 oldfs = get_fs(); 2178 oldfs = get_fs();
2177 set_fs(KERNEL_DS); 2179 set_fs(KERNEL_DS);
2178 /* The __user pointer casts are valid because of the set_fs() */ 2180 /* The __user pointer casts are valid because of the set_fs() */
diff --git a/fs/dcache.c b/fs/dcache.c
index 653f64ce98e2..939584648504 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -325,10 +325,13 @@ static struct dentry * __d_find_alias(struct inode *inode, int want_discon)
325 325
326struct dentry * d_find_alias(struct inode *inode) 326struct dentry * d_find_alias(struct inode *inode)
327{ 327{
328 struct dentry *de; 328 struct dentry *de = NULL;
329 spin_lock(&dcache_lock); 329
330 de = __d_find_alias(inode, 0); 330 if (!list_empty(&inode->i_dentry)) {
331 spin_unlock(&dcache_lock); 331 spin_lock(&dcache_lock);
332 de = __d_find_alias(inode, 0);
333 spin_unlock(&dcache_lock);
334 }
332 return de; 335 return de;
333} 336}
334 337
@@ -486,6 +489,7 @@ repeat:
486 continue; 489 continue;
487 } 490 }
488 prune_one_dentry(dentry); 491 prune_one_dentry(dentry);
492 cond_resched_lock(&dcache_lock);
489 goto repeat; 493 goto repeat;
490 } 494 }
491 spin_unlock(&dcache_lock); 495 spin_unlock(&dcache_lock);
@@ -799,6 +803,7 @@ void d_instantiate(struct dentry *entry, struct inode * inode)
799 if (inode) 803 if (inode)
800 list_add(&entry->d_alias, &inode->i_dentry); 804 list_add(&entry->d_alias, &inode->i_dentry);
801 entry->d_inode = inode; 805 entry->d_inode = inode;
806 fsnotify_d_instantiate(entry, inode);
802 spin_unlock(&dcache_lock); 807 spin_unlock(&dcache_lock);
803 security_d_instantiate(entry, inode); 808 security_d_instantiate(entry, inode);
804} 809}
@@ -850,6 +855,7 @@ struct dentry *d_instantiate_unique(struct dentry *entry, struct inode *inode)
850 list_add(&entry->d_alias, &inode->i_dentry); 855 list_add(&entry->d_alias, &inode->i_dentry);
851do_negative: 856do_negative:
852 entry->d_inode = inode; 857 entry->d_inode = inode;
858 fsnotify_d_instantiate(entry, inode);
853 spin_unlock(&dcache_lock); 859 spin_unlock(&dcache_lock);
854 security_d_instantiate(entry, inode); 860 security_d_instantiate(entry, inode);
855 return NULL; 861 return NULL;
@@ -980,6 +986,7 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
980 new = __d_find_alias(inode, 1); 986 new = __d_find_alias(inode, 1);
981 if (new) { 987 if (new) {
982 BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED)); 988 BUG_ON(!(new->d_flags & DCACHE_DISCONNECTED));
989 fsnotify_d_instantiate(new, inode);
983 spin_unlock(&dcache_lock); 990 spin_unlock(&dcache_lock);
984 security_d_instantiate(new, inode); 991 security_d_instantiate(new, inode);
985 d_rehash(dentry); 992 d_rehash(dentry);
@@ -989,6 +996,7 @@ struct dentry *d_splice_alias(struct inode *inode, struct dentry *dentry)
989 /* d_instantiate takes dcache_lock, so we do it by hand */ 996 /* d_instantiate takes dcache_lock, so we do it by hand */
990 list_add(&dentry->d_alias, &inode->i_dentry); 997 list_add(&dentry->d_alias, &inode->i_dentry);
991 dentry->d_inode = inode; 998 dentry->d_inode = inode;
999 fsnotify_d_instantiate(dentry, inode);
992 spin_unlock(&dcache_lock); 1000 spin_unlock(&dcache_lock);
993 security_d_instantiate(dentry, inode); 1001 security_d_instantiate(dentry, inode);
994 d_rehash(dentry); 1002 d_rehash(dentry);
@@ -1173,6 +1181,9 @@ void d_delete(struct dentry * dentry)
1173 spin_lock(&dentry->d_lock); 1181 spin_lock(&dentry->d_lock);
1174 isdir = S_ISDIR(dentry->d_inode->i_mode); 1182 isdir = S_ISDIR(dentry->d_inode->i_mode);
1175 if (atomic_read(&dentry->d_count) == 1) { 1183 if (atomic_read(&dentry->d_count) == 1) {
1184 /* remove this and other inotify debug checks after 2.6.18 */
1185 dentry->d_flags &= ~DCACHE_INOTIFY_PARENT_WATCHED;
1186
1176 dentry_iput(dentry); 1187 dentry_iput(dentry);
1177 fsnotify_nameremove(dentry, isdir); 1188 fsnotify_nameremove(dentry, isdir);
1178 return; 1189 return;
@@ -1339,6 +1350,7 @@ already_unhashed:
1339 1350
1340 list_add(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs); 1351 list_add(&dentry->d_u.d_child, &dentry->d_parent->d_subdirs);
1341 spin_unlock(&target->d_lock); 1352 spin_unlock(&target->d_lock);
1353 fsnotify_d_move(dentry);
1342 spin_unlock(&dentry->d_lock); 1354 spin_unlock(&dentry->d_lock);
1343 write_sequnlock(&rename_lock); 1355 write_sequnlock(&rename_lock);
1344 spin_unlock(&dcache_lock); 1356 spin_unlock(&dcache_lock);
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 27f3e787faca..235ed8d1f11e 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -129,6 +129,7 @@ struct dio {
129 /* AIO related stuff */ 129 /* AIO related stuff */
130 struct kiocb *iocb; /* kiocb */ 130 struct kiocb *iocb; /* kiocb */
131 int is_async; /* is IO async ? */ 131 int is_async; /* is IO async ? */
132 int io_error; /* IO error in completion path */
132 ssize_t result; /* IO result */ 133 ssize_t result; /* IO result */
133}; 134};
134 135
@@ -250,6 +251,10 @@ static void finished_one_bio(struct dio *dio)
250 ((offset + transferred) > dio->i_size)) 251 ((offset + transferred) > dio->i_size))
251 transferred = dio->i_size - offset; 252 transferred = dio->i_size - offset;
252 253
254 /* check for error in completion path */
255 if (dio->io_error)
256 transferred = dio->io_error;
257
253 dio_complete(dio, offset, transferred); 258 dio_complete(dio, offset, transferred);
254 259
255 /* Complete AIO later if falling back to buffered i/o */ 260 /* Complete AIO later if falling back to buffered i/o */
@@ -406,7 +411,7 @@ static int dio_bio_complete(struct dio *dio, struct bio *bio)
406 int page_no; 411 int page_no;
407 412
408 if (!uptodate) 413 if (!uptodate)
409 dio->result = -EIO; 414 dio->io_error = -EIO;
410 415
411 if (dio->is_async && dio->rw == READ) { 416 if (dio->is_async && dio->rw == READ) {
412 bio_check_pages_dirty(bio); /* transfers ownership */ 417 bio_check_pages_dirty(bio); /* transfers ownership */
@@ -971,6 +976,7 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode,
971 dio->next_block_for_io = -1; 976 dio->next_block_for_io = -1;
972 977
973 dio->page_errors = 0; 978 dio->page_errors = 0;
979 dio->io_error = 0;
974 dio->result = 0; 980 dio->result = 0;
975 dio->iocb = iocb; 981 dio->iocb = iocb;
976 dio->i_size = i_size_read(inode); 982 dio->i_size = i_size_read(inode);
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 1c2b16fda13a..a0f682cdd03e 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -599,7 +599,7 @@ sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event __user *event)
599 switch (op) { 599 switch (op) {
600 case EPOLL_CTL_ADD: 600 case EPOLL_CTL_ADD:
601 if (!epi) { 601 if (!epi) {
602 epds.events |= POLLERR | POLLHUP; 602 epds.events |= POLLERR | POLLHUP | POLLRDHUP;
603 603
604 error = ep_insert(ep, &epds, tfile, fd); 604 error = ep_insert(ep, &epds, tfile, fd);
605 } else 605 } else
@@ -613,7 +613,7 @@ sys_epoll_ctl(int epfd, int op, int fd, struct epoll_event __user *event)
613 break; 613 break;
614 case EPOLL_CTL_MOD: 614 case EPOLL_CTL_MOD:
615 if (epi) { 615 if (epi) {
616 epds.events |= POLLERR | POLLHUP; 616 epds.events |= POLLERR | POLLHUP | POLLRDHUP;
617 error = ep_modify(ep, epi, &epds); 617 error = ep_modify(ep, epi, &epds);
618 } else 618 } else
619 error = -ENOENT; 619 error = -ENOENT;
diff --git a/fs/exec.c b/fs/exec.c
index 0b515ac53134..995cba3c62b8 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -127,7 +127,7 @@ asmlinkage long sys_uselib(const char __user * library)
127 struct nameidata nd; 127 struct nameidata nd;
128 int error; 128 int error;
129 129
130 error = __user_path_lookup_open(library, LOOKUP_FOLLOW, &nd, FMODE_READ); 130 error = __user_path_lookup_open(library, LOOKUP_FOLLOW, &nd, FMODE_READ|FMODE_EXEC);
131 if (error) 131 if (error)
132 goto out; 132 goto out;
133 133
@@ -477,7 +477,7 @@ struct file *open_exec(const char *name)
477 int err; 477 int err;
478 struct file *file; 478 struct file *file;
479 479
480 err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd, FMODE_READ); 480 err = path_lookup_open(AT_FDCWD, name, LOOKUP_FOLLOW, &nd, FMODE_READ|FMODE_EXEC);
481 file = ERR_PTR(err); 481 file = ERR_PTR(err);
482 482
483 if (!err) { 483 if (!err) {
@@ -1143,10 +1143,9 @@ int do_execve(char * filename,
1143 int i; 1143 int i;
1144 1144
1145 retval = -ENOMEM; 1145 retval = -ENOMEM;
1146 bprm = kmalloc(sizeof(*bprm), GFP_KERNEL); 1146 bprm = kzalloc(sizeof(*bprm), GFP_KERNEL);
1147 if (!bprm) 1147 if (!bprm)
1148 goto out_ret; 1148 goto out_ret;
1149 memset(bprm, 0, sizeof(*bprm));
1150 1149
1151 file = open_exec(filename); 1150 file = open_exec(filename);
1152 retval = PTR_ERR(file); 1151 retval = PTR_ERR(file);
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index 268b73f5847c..7e30bae174ed 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -211,8 +211,6 @@ static int ext2_show_options(struct seq_file *seq, struct vfsmount *vfs)
211 211
212 if (sbi->s_mount_opt & EXT2_MOUNT_GRPID) 212 if (sbi->s_mount_opt & EXT2_MOUNT_GRPID)
213 seq_puts(seq, ",grpid"); 213 seq_puts(seq, ",grpid");
214 else
215 seq_puts(seq, ",nogrpid");
216 214
217#if defined(CONFIG_QUOTA) 215#if defined(CONFIG_QUOTA)
218 if (sbi->s_mount_opt & EXT2_MOUNT_USRQUOTA) 216 if (sbi->s_mount_opt & EXT2_MOUNT_USRQUOTA)
diff --git a/fs/ext3/bitmap.c b/fs/ext3/bitmap.c
index cb16b4c5d5df..ce4f82b9e528 100644
--- a/fs/ext3/bitmap.c
+++ b/fs/ext3/bitmap.c
@@ -7,11 +7,11 @@
7 * Universite Pierre et Marie Curie (Paris VI) 7 * Universite Pierre et Marie Curie (Paris VI)
8 */ 8 */
9 9
10#ifdef EXT3FS_DEBUG
11
12#include <linux/buffer_head.h> 10#include <linux/buffer_head.h>
11#include <linux/jbd.h>
12#include <linux/ext3_fs.h>
13 13
14#include "ext3_fs.h" 14#ifdef EXT3FS_DEBUG
15 15
16static int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0}; 16static int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0};
17 17
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 785c7213a54f..f3fbe2d030f4 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -381,8 +381,8 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc)
381 list_move(&inode->i_list, &sb->s_dirty); 381 list_move(&inode->i_list, &sb->s_dirty);
382 } 382 }
383 spin_unlock(&inode_lock); 383 spin_unlock(&inode_lock);
384 cond_resched();
385 iput(inode); 384 iput(inode);
385 cond_resched();
386 spin_lock(&inode_lock); 386 spin_lock(&inode_lock);
387 if (wbc->nr_to_write <= 0) 387 if (wbc->nr_to_write <= 0)
388 break; 388 break;
diff --git a/fs/inode.c b/fs/inode.c
index a51c671c54cf..85da11044adc 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -91,7 +91,7 @@ DEFINE_SPINLOCK(inode_lock);
91 * from its final dispose_list, the struct super_block they refer to 91 * from its final dispose_list, the struct super_block they refer to
92 * (for inode->i_sb->s_op) may already have been freed and reused. 92 * (for inode->i_sb->s_op) may already have been freed and reused.
93 */ 93 */
94DEFINE_MUTEX(iprune_mutex); 94static DEFINE_MUTEX(iprune_mutex);
95 95
96/* 96/*
97 * Statistics gathering.. 97 * Statistics gathering..
diff --git a/fs/inotify.c b/fs/inotify.c
index 0ee39ef591c6..a61e93e17853 100644
--- a/fs/inotify.c
+++ b/fs/inotify.c
@@ -38,7 +38,6 @@
38#include <asm/ioctls.h> 38#include <asm/ioctls.h>
39 39
40static atomic_t inotify_cookie; 40static atomic_t inotify_cookie;
41static atomic_t inotify_watches;
42 41
43static kmem_cache_t *watch_cachep; 42static kmem_cache_t *watch_cachep;
44static kmem_cache_t *event_cachep; 43static kmem_cache_t *event_cachep;
@@ -381,6 +380,48 @@ static int find_inode(const char __user *dirname, struct nameidata *nd,
381} 380}
382 381
383/* 382/*
383 * inotify_inode_watched - returns nonzero if there are watches on this inode
384 * and zero otherwise. We call this lockless, we do not care if we race.
385 */
386static inline int inotify_inode_watched(struct inode *inode)
387{
388 return !list_empty(&inode->inotify_watches);
389}
390
391/*
392 * Get child dentry flag into synch with parent inode.
393 * Flag should always be clear for negative dentrys.
394 */
395static void set_dentry_child_flags(struct inode *inode, int watched)
396{
397 struct dentry *alias;
398
399 spin_lock(&dcache_lock);
400 list_for_each_entry(alias, &inode->i_dentry, d_alias) {
401 struct dentry *child;
402
403 list_for_each_entry(child, &alias->d_subdirs, d_u.d_child) {
404 if (!child->d_inode) {
405 WARN_ON(child->d_flags & DCACHE_INOTIFY_PARENT_WATCHED);
406 continue;
407 }
408 spin_lock(&child->d_lock);
409 if (watched) {
410 WARN_ON(child->d_flags &
411 DCACHE_INOTIFY_PARENT_WATCHED);
412 child->d_flags |= DCACHE_INOTIFY_PARENT_WATCHED;
413 } else {
414 WARN_ON(!(child->d_flags &
415 DCACHE_INOTIFY_PARENT_WATCHED));
416 child->d_flags&=~DCACHE_INOTIFY_PARENT_WATCHED;
417 }
418 spin_unlock(&child->d_lock);
419 }
420 }
421 spin_unlock(&dcache_lock);
422}
423
424/*
384 * create_watch - creates a watch on the given device. 425 * create_watch - creates a watch on the given device.
385 * 426 *
386 * Callers must hold dev->mutex. Calls inotify_dev_get_wd() so may sleep. 427 * Callers must hold dev->mutex. Calls inotify_dev_get_wd() so may sleep.
@@ -426,7 +467,6 @@ static struct inotify_watch *create_watch(struct inotify_device *dev,
426 get_inotify_watch(watch); 467 get_inotify_watch(watch);
427 468
428 atomic_inc(&dev->user->inotify_watches); 469 atomic_inc(&dev->user->inotify_watches);
429 atomic_inc(&inotify_watches);
430 470
431 return watch; 471 return watch;
432} 472}
@@ -458,8 +498,10 @@ static void remove_watch_no_event(struct inotify_watch *watch,
458 list_del(&watch->i_list); 498 list_del(&watch->i_list);
459 list_del(&watch->d_list); 499 list_del(&watch->d_list);
460 500
501 if (!inotify_inode_watched(watch->inode))
502 set_dentry_child_flags(watch->inode, 0);
503
461 atomic_dec(&dev->user->inotify_watches); 504 atomic_dec(&dev->user->inotify_watches);
462 atomic_dec(&inotify_watches);
463 idr_remove(&dev->idr, watch->wd); 505 idr_remove(&dev->idr, watch->wd);
464 put_inotify_watch(watch); 506 put_inotify_watch(watch);
465} 507}
@@ -481,16 +523,39 @@ static void remove_watch(struct inotify_watch *watch,struct inotify_device *dev)
481 remove_watch_no_event(watch, dev); 523 remove_watch_no_event(watch, dev);
482} 524}
483 525
526/* Kernel API */
527
484/* 528/*
485 * inotify_inode_watched - returns nonzero if there are watches on this inode 529 * inotify_d_instantiate - instantiate dcache entry for inode
486 * and zero otherwise. We call this lockless, we do not care if we race.
487 */ 530 */
488static inline int inotify_inode_watched(struct inode *inode) 531void inotify_d_instantiate(struct dentry *entry, struct inode *inode)
489{ 532{
490 return !list_empty(&inode->inotify_watches); 533 struct dentry *parent;
534
535 if (!inode)
536 return;
537
538 WARN_ON(entry->d_flags & DCACHE_INOTIFY_PARENT_WATCHED);
539 spin_lock(&entry->d_lock);
540 parent = entry->d_parent;
541 if (inotify_inode_watched(parent->d_inode))
542 entry->d_flags |= DCACHE_INOTIFY_PARENT_WATCHED;
543 spin_unlock(&entry->d_lock);
491} 544}
492 545
493/* Kernel API */ 546/*
547 * inotify_d_move - dcache entry has been moved
548 */
549void inotify_d_move(struct dentry *entry)
550{
551 struct dentry *parent;
552
553 parent = entry->d_parent;
554 if (inotify_inode_watched(parent->d_inode))
555 entry->d_flags |= DCACHE_INOTIFY_PARENT_WATCHED;
556 else
557 entry->d_flags &= ~DCACHE_INOTIFY_PARENT_WATCHED;
558}
494 559
495/** 560/**
496 * inotify_inode_queue_event - queue an event to all watches on this inode 561 * inotify_inode_queue_event - queue an event to all watches on this inode
@@ -538,7 +603,7 @@ void inotify_dentry_parent_queue_event(struct dentry *dentry, u32 mask,
538 struct dentry *parent; 603 struct dentry *parent;
539 struct inode *inode; 604 struct inode *inode;
540 605
541 if (!atomic_read (&inotify_watches)) 606 if (!(dentry->d_flags & DCACHE_INOTIFY_PARENT_WATCHED))
542 return; 607 return;
543 608
544 spin_lock(&dentry->d_lock); 609 spin_lock(&dentry->d_lock);
@@ -993,6 +1058,9 @@ asmlinkage long sys_inotify_add_watch(int fd, const char __user *path, u32 mask)
993 goto out; 1058 goto out;
994 } 1059 }
995 1060
1061 if (!inotify_inode_watched(inode))
1062 set_dentry_child_flags(inode, 1);
1063
996 /* Add the watch to the device's and the inode's list */ 1064 /* Add the watch to the device's and the inode's list */
997 list_add(&watch->d_list, &dev->watches); 1065 list_add(&watch->d_list, &dev->watches);
998 list_add(&watch->i_list, &inode->inotify_watches); 1066 list_add(&watch->i_list, &inode->inotify_watches);
@@ -1065,7 +1133,6 @@ static int __init inotify_setup(void)
1065 inotify_max_user_watches = 8192; 1133 inotify_max_user_watches = 8192;
1066 1134
1067 atomic_set(&inotify_cookie, 0); 1135 atomic_set(&inotify_cookie, 0);
1068 atomic_set(&inotify_watches, 0);
1069 1136
1070 watch_cachep = kmem_cache_create("inotify_watch_cache", 1137 watch_cachep = kmem_cache_create("inotify_watch_cache",
1071 sizeof(struct inotify_watch), 1138 sizeof(struct inotify_watch),
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c
index 95a628d8cac8..7f96b5cb6781 100644
--- a/fs/jbd/journal.c
+++ b/fs/jbd/journal.c
@@ -33,9 +33,11 @@
33#include <linux/mm.h> 33#include <linux/mm.h>
34#include <linux/suspend.h> 34#include <linux/suspend.h>
35#include <linux/pagemap.h> 35#include <linux/pagemap.h>
36#include <linux/kthread.h>
37#include <linux/proc_fs.h>
38
36#include <asm/uaccess.h> 39#include <asm/uaccess.h>
37#include <asm/page.h> 40#include <asm/page.h>
38#include <linux/proc_fs.h>
39 41
40EXPORT_SYMBOL(journal_start); 42EXPORT_SYMBOL(journal_start);
41EXPORT_SYMBOL(journal_restart); 43EXPORT_SYMBOL(journal_restart);
@@ -111,18 +113,15 @@ static void commit_timeout(unsigned long __data)
111 113
112static int kjournald(void *arg) 114static int kjournald(void *arg)
113{ 115{
114 journal_t *journal = (journal_t *) arg; 116 journal_t *journal = arg;
115 transaction_t *transaction; 117 transaction_t *transaction;
116 struct timer_list timer;
117 118
118 daemonize("kjournald"); 119 /*
119 120 * Set up an interval timer which can be used to trigger a commit wakeup
120 /* Set up an interval timer which can be used to trigger a 121 * after the commit interval expires
121 commit wakeup after the commit interval expires */ 122 */
122 init_timer(&timer); 123 setup_timer(&journal->j_commit_timer, commit_timeout,
123 timer.data = (unsigned long) current; 124 (unsigned long)current);
124 timer.function = commit_timeout;
125 journal->j_commit_timer = &timer;
126 125
127 /* Record that the journal thread is running */ 126 /* Record that the journal thread is running */
128 journal->j_task = current; 127 journal->j_task = current;
@@ -146,7 +145,7 @@ loop:
146 if (journal->j_commit_sequence != journal->j_commit_request) { 145 if (journal->j_commit_sequence != journal->j_commit_request) {
147 jbd_debug(1, "OK, requests differ\n"); 146 jbd_debug(1, "OK, requests differ\n");
148 spin_unlock(&journal->j_state_lock); 147 spin_unlock(&journal->j_state_lock);
149 del_timer_sync(journal->j_commit_timer); 148 del_timer_sync(&journal->j_commit_timer);
150 journal_commit_transaction(journal); 149 journal_commit_transaction(journal);
151 spin_lock(&journal->j_state_lock); 150 spin_lock(&journal->j_state_lock);
152 goto loop; 151 goto loop;
@@ -203,7 +202,7 @@ loop:
203 202
204end_loop: 203end_loop:
205 spin_unlock(&journal->j_state_lock); 204 spin_unlock(&journal->j_state_lock);
206 del_timer_sync(journal->j_commit_timer); 205 del_timer_sync(&journal->j_commit_timer);
207 journal->j_task = NULL; 206 journal->j_task = NULL;
208 wake_up(&journal->j_wait_done_commit); 207 wake_up(&journal->j_wait_done_commit);
209 jbd_debug(1, "Journal thread exiting.\n"); 208 jbd_debug(1, "Journal thread exiting.\n");
@@ -212,7 +211,7 @@ end_loop:
212 211
213static void journal_start_thread(journal_t *journal) 212static void journal_start_thread(journal_t *journal)
214{ 213{
215 kernel_thread(kjournald, journal, CLONE_VM|CLONE_FS|CLONE_FILES); 214 kthread_run(kjournald, journal, "kjournald");
216 wait_event(journal->j_wait_done_commit, journal->j_task != 0); 215 wait_event(journal->j_wait_done_commit, journal->j_task != 0);
217} 216}
218 217
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c
index 5fc40888f4cf..ada31fa272e3 100644
--- a/fs/jbd/transaction.c
+++ b/fs/jbd/transaction.c
@@ -53,8 +53,8 @@ get_transaction(journal_t *journal, transaction_t *transaction)
53 spin_lock_init(&transaction->t_handle_lock); 53 spin_lock_init(&transaction->t_handle_lock);
54 54
55 /* Set up the commit timer for the new transaction. */ 55 /* Set up the commit timer for the new transaction. */
56 journal->j_commit_timer->expires = transaction->t_expires; 56 journal->j_commit_timer.expires = transaction->t_expires;
57 add_timer(journal->j_commit_timer); 57 add_timer(&journal->j_commit_timer);
58 58
59 J_ASSERT(journal->j_running_transaction == NULL); 59 J_ASSERT(journal->j_running_transaction == NULL);
60 journal->j_running_transaction = transaction; 60 journal->j_running_transaction = transaction;
diff --git a/fs/minix/bitmap.c b/fs/minix/bitmap.c
index dc6a4e4abcdc..4a6abc49418e 100644
--- a/fs/minix/bitmap.c
+++ b/fs/minix/bitmap.c
@@ -56,7 +56,7 @@ void minix_free_block(struct inode * inode, int block)
56 unsigned int bit,zone; 56 unsigned int bit,zone;
57 57
58 if (block < sbi->s_firstdatazone || block >= sbi->s_nzones) { 58 if (block < sbi->s_firstdatazone || block >= sbi->s_nzones) {
59 printk("trying to free block not in datazone\n"); 59 printk("Trying to free block not in datazone\n");
60 return; 60 return;
61 } 61 }
62 zone = block - sbi->s_firstdatazone + 1; 62 zone = block - sbi->s_firstdatazone + 1;
@@ -124,7 +124,7 @@ minix_V1_raw_inode(struct super_block *sb, ino_t ino, struct buffer_head **bh)
124 ino / MINIX_INODES_PER_BLOCK; 124 ino / MINIX_INODES_PER_BLOCK;
125 *bh = sb_bread(sb, block); 125 *bh = sb_bread(sb, block);
126 if (!*bh) { 126 if (!*bh) {
127 printk("unable to read i-node block\n"); 127 printk("Unable to read inode block\n");
128 return NULL; 128 return NULL;
129 } 129 }
130 p = (void *)(*bh)->b_data; 130 p = (void *)(*bh)->b_data;
@@ -149,7 +149,7 @@ minix_V2_raw_inode(struct super_block *sb, ino_t ino, struct buffer_head **bh)
149 ino / MINIX2_INODES_PER_BLOCK; 149 ino / MINIX2_INODES_PER_BLOCK;
150 *bh = sb_bread(sb, block); 150 *bh = sb_bread(sb, block);
151 if (!*bh) { 151 if (!*bh) {
152 printk("unable to read i-node block\n"); 152 printk("Unable to read inode block\n");
153 return NULL; 153 return NULL;
154 } 154 }
155 p = (void *)(*bh)->b_data; 155 p = (void *)(*bh)->b_data;
@@ -204,7 +204,7 @@ void minix_free_inode(struct inode * inode)
204 bh = sbi->s_imap[ino >> 13]; 204 bh = sbi->s_imap[ino >> 13];
205 lock_kernel(); 205 lock_kernel();
206 if (!minix_test_and_clear_bit(ino & 8191, bh->b_data)) 206 if (!minix_test_and_clear_bit(ino & 8191, bh->b_data))
207 printk("minix_free_inode: bit %lu already cleared.\n", ino); 207 printk("minix_free_inode: bit %lu already cleared\n", ino);
208 unlock_kernel(); 208 unlock_kernel();
209 mark_buffer_dirty(bh); 209 mark_buffer_dirty(bh);
210 out: 210 out:
@@ -238,7 +238,7 @@ struct inode * minix_new_inode(const struct inode * dir, int * error)
238 return NULL; 238 return NULL;
239 } 239 }
240 if (minix_test_and_set_bit(j,bh->b_data)) { /* shouldn't happen */ 240 if (minix_test_and_set_bit(j,bh->b_data)) { /* shouldn't happen */
241 printk("new_inode: bit already set"); 241 printk("new_inode: bit already set\n");
242 unlock_kernel(); 242 unlock_kernel();
243 iput(inode); 243 iput(inode);
244 return NULL; 244 return NULL;
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index d9ffc43fee59..2dcccf1d1b7f 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -127,11 +127,11 @@ static int minix_remount (struct super_block * sb, int * flags, char * data)
127 mark_buffer_dirty(sbi->s_sbh); 127 mark_buffer_dirty(sbi->s_sbh);
128 128
129 if (!(sbi->s_mount_state & MINIX_VALID_FS)) 129 if (!(sbi->s_mount_state & MINIX_VALID_FS))
130 printk ("MINIX-fs warning: remounting unchecked fs, " 130 printk("MINIX-fs warning: remounting unchecked fs, "
131 "running fsck is recommended.\n"); 131 "running fsck is recommended\n");
132 else if ((sbi->s_mount_state & MINIX_ERROR_FS)) 132 else if ((sbi->s_mount_state & MINIX_ERROR_FS))
133 printk ("MINIX-fs warning: remounting fs with errors, " 133 printk("MINIX-fs warning: remounting fs with errors, "
134 "running fsck is recommended.\n"); 134 "running fsck is recommended\n");
135 } 135 }
136 return 0; 136 return 0;
137} 137}
@@ -245,11 +245,11 @@ static int minix_fill_super(struct super_block *s, void *data, int silent)
245 mark_buffer_dirty(bh); 245 mark_buffer_dirty(bh);
246 } 246 }
247 if (!(sbi->s_mount_state & MINIX_VALID_FS)) 247 if (!(sbi->s_mount_state & MINIX_VALID_FS))
248 printk ("MINIX-fs: mounting unchecked file system, " 248 printk("MINIX-fs: mounting unchecked file system, "
249 "running fsck is recommended.\n"); 249 "running fsck is recommended\n");
250 else if (sbi->s_mount_state & MINIX_ERROR_FS) 250 else if (sbi->s_mount_state & MINIX_ERROR_FS)
251 printk ("MINIX-fs: mounting file system with errors, " 251 printk("MINIX-fs: mounting file system with errors, "
252 "running fsck is recommended.\n"); 252 "running fsck is recommended\n");
253 return 0; 253 return 0;
254 254
255out_iput: 255out_iput:
@@ -273,19 +273,19 @@ out_no_bitmap:
273 273
274out_no_map: 274out_no_map:
275 if (!silent) 275 if (!silent)
276 printk ("MINIX-fs: can't allocate map\n"); 276 printk("MINIX-fs: can't allocate map\n");
277 goto out_release; 277 goto out_release;
278 278
279out_no_fs: 279out_no_fs:
280 if (!silent) 280 if (!silent)
281 printk("VFS: Can't find a Minix or Minix V2 filesystem on device " 281 printk("VFS: Can't find a Minix or Minix V2 filesystem "
282 "%s.\n", s->s_id); 282 "on device %s\n", s->s_id);
283 out_release: 283 out_release:
284 brelse(bh); 284 brelse(bh);
285 goto out; 285 goto out;
286 286
287out_bad_hblock: 287out_bad_hblock:
288 printk("MINIX-fs: blocksize too small for device.\n"); 288 printk("MINIX-fs: blocksize too small for device\n");
289 goto out; 289 goto out;
290 290
291out_bad_sb: 291out_bad_sb:
@@ -524,7 +524,7 @@ int minix_sync_inode(struct inode * inode)
524 sync_dirty_buffer(bh); 524 sync_dirty_buffer(bh);
525 if (buffer_req(bh) && !buffer_uptodate(bh)) 525 if (buffer_req(bh) && !buffer_uptodate(bh))
526 { 526 {
527 printk ("IO error syncing minix inode [%s:%08lx]\n", 527 printk("IO error syncing minix inode [%s:%08lx]\n",
528 inode->i_sb->s_id, inode->i_ino); 528 inode->i_sb->s_id, inode->i_ino);
529 err = -1; 529 err = -1;
530 } 530 }
diff --git a/fs/minix/itree_v1.c b/fs/minix/itree_v1.c
index ba06aef4aca1..656b1347a25b 100644
--- a/fs/minix/itree_v1.c
+++ b/fs/minix/itree_v1.c
@@ -25,9 +25,9 @@ static int block_to_path(struct inode * inode, long block, int offsets[DEPTH])
25 int n = 0; 25 int n = 0;
26 26
27 if (block < 0) { 27 if (block < 0) {
28 printk("minix_bmap: block<0"); 28 printk("minix_bmap: block<0\n");
29 } else if (block >= (minix_sb(inode->i_sb)->s_max_size/BLOCK_SIZE)) { 29 } else if (block >= (minix_sb(inode->i_sb)->s_max_size/BLOCK_SIZE)) {
30 printk("minix_bmap: block>big"); 30 printk("minix_bmap: block>big\n");
31 } else if (block < 7) { 31 } else if (block < 7) {
32 offsets[n++] = block; 32 offsets[n++] = block;
33 } else if ((block -= 7) < 512) { 33 } else if ((block -= 7) < 512) {
diff --git a/fs/minix/itree_v2.c b/fs/minix/itree_v2.c
index 3adc7675560f..9adcdc754e0f 100644
--- a/fs/minix/itree_v2.c
+++ b/fs/minix/itree_v2.c
@@ -25,9 +25,9 @@ static int block_to_path(struct inode * inode, long block, int offsets[DEPTH])
25 int n = 0; 25 int n = 0;
26 26
27 if (block < 0) { 27 if (block < 0) {
28 printk("minix_bmap: block<0"); 28 printk("minix_bmap: block<0\n");
29 } else if (block >= (minix_sb(inode->i_sb)->s_max_size/BLOCK_SIZE)) { 29 } else if (block >= (minix_sb(inode->i_sb)->s_max_size/BLOCK_SIZE)) {
30 printk("minix_bmap: block>big"); 30 printk("minix_bmap: block>big\n");
31 } else if (block < 7) { 31 } else if (block < 7) {
32 offsets[n++] = block; 32 offsets[n++] = block;
33 } else if ((block -= 7) < 256) { 33 } else if ((block -= 7) < 256) {
diff --git a/fs/namei.c b/fs/namei.c
index c72b940797fc..712dfc77793b 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1628,6 +1628,12 @@ do_last:
1628 goto exit; 1628 goto exit;
1629 } 1629 }
1630 1630
1631 if (IS_ERR(nd->intent.open.file)) {
1632 mutex_unlock(&dir->d_inode->i_mutex);
1633 error = PTR_ERR(nd->intent.open.file);
1634 goto exit_dput;
1635 }
1636
1631 /* Negative dentry, just create the file */ 1637 /* Negative dentry, just create the file */
1632 if (!path.dentry->d_inode) { 1638 if (!path.dentry->d_inode) {
1633 if (!IS_POSIXACL(dir->d_inode)) 1639 if (!IS_POSIXACL(dir->d_inode))
@@ -2621,16 +2627,27 @@ int __page_symlink(struct inode *inode, const char *symname, int len,
2621 int err = -ENOMEM; 2627 int err = -ENOMEM;
2622 char *kaddr; 2628 char *kaddr;
2623 2629
2630retry:
2624 page = find_or_create_page(mapping, 0, gfp_mask); 2631 page = find_or_create_page(mapping, 0, gfp_mask);
2625 if (!page) 2632 if (!page)
2626 goto fail; 2633 goto fail;
2627 err = mapping->a_ops->prepare_write(NULL, page, 0, len-1); 2634 err = mapping->a_ops->prepare_write(NULL, page, 0, len-1);
2635 if (err == AOP_TRUNCATED_PAGE) {
2636 page_cache_release(page);
2637 goto retry;
2638 }
2628 if (err) 2639 if (err)
2629 goto fail_map; 2640 goto fail_map;
2630 kaddr = kmap_atomic(page, KM_USER0); 2641 kaddr = kmap_atomic(page, KM_USER0);
2631 memcpy(kaddr, symname, len-1); 2642 memcpy(kaddr, symname, len-1);
2632 kunmap_atomic(kaddr, KM_USER0); 2643 kunmap_atomic(kaddr, KM_USER0);
2633 mapping->a_ops->commit_write(NULL, page, 0, len-1); 2644 err = mapping->a_ops->commit_write(NULL, page, 0, len-1);
2645 if (err == AOP_TRUNCATED_PAGE) {
2646 page_cache_release(page);
2647 goto retry;
2648 }
2649 if (err)
2650 goto fail_map;
2634 /* 2651 /*
2635 * Notice that we are _not_ going to block here - end of page is 2652 * Notice that we are _not_ going to block here - end of page is
2636 * unmapped, so this will only try to map the rest of page, see 2653 * unmapped, so this will only try to map the rest of page, see
@@ -2640,7 +2657,8 @@ int __page_symlink(struct inode *inode, const char *symname, int len,
2640 */ 2657 */
2641 if (!PageUptodate(page)) { 2658 if (!PageUptodate(page)) {
2642 err = mapping->a_ops->readpage(NULL, page); 2659 err = mapping->a_ops->readpage(NULL, page);
2643 wait_on_page_locked(page); 2660 if (err != AOP_TRUNCATED_PAGE)
2661 wait_on_page_locked(page);
2644 } else { 2662 } else {
2645 unlock_page(page); 2663 unlock_page(page);
2646 } 2664 }
diff --git a/fs/open.c b/fs/open.c
index 1091dadd6c38..7d02d19bd0a2 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -890,6 +890,10 @@ EXPORT_SYMBOL(filp_open);
890 * a fully instantiated struct file to the caller. 890 * a fully instantiated struct file to the caller.
891 * This function is meant to be called from within a filesystem's 891 * This function is meant to be called from within a filesystem's
892 * lookup method. 892 * lookup method.
893 * Beware of calling it for non-regular files! Those ->open methods might block
894 * (e.g. in fifo_open), leaving you with parent locked (and in case of fifo,
895 * leading to a deadlock, as nobody can open that fifo anymore, because
896 * another process to open fifo will block on locked parent when doing lookup).
893 * Note that in case of error, nd->intent.open.file is destroyed, but the 897 * Note that in case of error, nd->intent.open.file is destroyed, but the
894 * path information remains valid. 898 * path information remains valid.
895 * If the open callback is set to NULL, then the standard f_op->open() 899 * If the open callback is set to NULL, then the standard f_op->open()
diff --git a/fs/pipe.c b/fs/pipe.c
index 8aada8e426f4..d976866a115b 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -662,10 +662,9 @@ struct inode* pipe_new(struct inode* inode)
662{ 662{
663 struct pipe_inode_info *info; 663 struct pipe_inode_info *info;
664 664
665 info = kmalloc(sizeof(struct pipe_inode_info), GFP_KERNEL); 665 info = kzalloc(sizeof(struct pipe_inode_info), GFP_KERNEL);
666 if (!info) 666 if (!info)
667 goto fail_page; 667 goto fail_page;
668 memset(info, 0, sizeof(*info));
669 inode->i_pipe = info; 668 inode->i_pipe = info;
670 669
671 init_waitqueue_head(PIPE_WAIT(*inode)); 670 init_waitqueue_head(PIPE_WAIT(*inode));
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index 826c131994c3..1e9ea37d457e 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -485,6 +485,40 @@ static struct file_operations proc_slabinfo_operations = {
485 .llseek = seq_lseek, 485 .llseek = seq_lseek,
486 .release = seq_release, 486 .release = seq_release,
487}; 487};
488
489#ifdef CONFIG_DEBUG_SLAB_LEAK
490extern struct seq_operations slabstats_op;
491static int slabstats_open(struct inode *inode, struct file *file)
492{
493 unsigned long *n = kzalloc(PAGE_SIZE, GFP_KERNEL);
494 int ret = -ENOMEM;
495 if (n) {
496 ret = seq_open(file, &slabstats_op);
497 if (!ret) {
498 struct seq_file *m = file->private_data;
499 *n = PAGE_SIZE / (2 * sizeof(unsigned long));
500 m->private = n;
501 n = NULL;
502 }
503 kfree(n);
504 }
505 return ret;
506}
507
508static int slabstats_release(struct inode *inode, struct file *file)
509{
510 struct seq_file *m = file->private_data;
511 kfree(m->private);
512 return seq_release(inode, file);
513}
514
515static struct file_operations proc_slabstats_operations = {
516 .open = slabstats_open,
517 .read = seq_read,
518 .llseek = seq_lseek,
519 .release = slabstats_release,
520};
521#endif
488#endif 522#endif
489 523
490static int show_stat(struct seq_file *p, void *v) 524static int show_stat(struct seq_file *p, void *v)
@@ -744,6 +778,9 @@ void __init proc_misc_init(void)
744 create_seq_entry("interrupts", 0, &proc_interrupts_operations); 778 create_seq_entry("interrupts", 0, &proc_interrupts_operations);
745#ifdef CONFIG_SLAB 779#ifdef CONFIG_SLAB
746 create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations); 780 create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
781#ifdef CONFIG_DEBUG_SLAB_LEAK
782 create_seq_entry("slab_allocators", 0 ,&proc_slabstats_operations);
783#endif
747#endif 784#endif
748 create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations); 785 create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations);
749 create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations); 786 create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations);
diff --git a/fs/read_write.c b/fs/read_write.c
index 3f7a1a62165f..34b1bf259efd 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -470,7 +470,7 @@ static ssize_t do_readv_writev(int type, struct file *file,
470 * verify all the pointers 470 * verify all the pointers
471 */ 471 */
472 ret = -EINVAL; 472 ret = -EINVAL;
473 if ((nr_segs > UIO_MAXIOV) || (nr_segs <= 0)) 473 if (nr_segs > UIO_MAXIOV)
474 goto out; 474 goto out;
475 if (!file->f_op) 475 if (!file->f_op)
476 goto out; 476 goto out;
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index be12879bb179..d0c1e865963e 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -1532,7 +1532,7 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t
1532 buf += write_bytes; 1532 buf += write_bytes;
1533 *ppos = pos += write_bytes; 1533 *ppos = pos += write_bytes;
1534 count -= write_bytes; 1534 count -= write_bytes;
1535 balance_dirty_pages_ratelimited(inode->i_mapping); 1535 balance_dirty_pages_ratelimited_nr(inode->i_mapping, num_pages);
1536 } 1536 }
1537 1537
1538 /* this is only true on error */ 1538 /* this is only true on error */
@@ -1546,10 +1546,10 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t
1546 } 1546 }
1547 } 1547 }
1548 1548
1549 if ((file->f_flags & O_SYNC) || IS_SYNC(inode)) 1549 if (likely(res >= 0) &&
1550 res = 1550 (unlikely((file->f_flags & O_SYNC) || IS_SYNC(inode))))
1551 generic_osync_inode(inode, file->f_mapping, 1551 res = generic_osync_inode(inode, file->f_mapping,
1552 OSYNC_METADATA | OSYNC_DATA); 1552 OSYNC_METADATA | OSYNC_DATA);
1553 1553
1554 mutex_unlock(&inode->i_mutex); 1554 mutex_unlock(&inode->i_mutex);
1555 reiserfs_async_progress_wait(inode->i_sb); 1555 reiserfs_async_progress_wait(inode->i_sb);
diff --git a/fs/reiserfs/fix_node.c b/fs/reiserfs/fix_node.c
index aa22588019ec..5600d3d60cf7 100644
--- a/fs/reiserfs/fix_node.c
+++ b/fs/reiserfs/fix_node.c
@@ -191,9 +191,7 @@ static void create_virtual_node(struct tree_balance *tb, int h)
191 "vs-8045: create_virtual_node: rdkey %k, affected item==%d (mode==%c) Must be %c", 191 "vs-8045: create_virtual_node: rdkey %k, affected item==%d (mode==%c) Must be %c",
192 key, vn->vn_affected_item_num, 192 key, vn->vn_affected_item_num,
193 vn->vn_mode, M_DELETE); 193 vn->vn_mode, M_DELETE);
194 } else 194 }
195 /* we can delete directory item, that has only one directory entry in it */
196 ;
197 } 195 }
198#endif 196#endif
199 197
diff --git a/fs/reiserfs/item_ops.c b/fs/reiserfs/item_ops.c
index e237cd668e5b..7a88adbceef6 100644
--- a/fs/reiserfs/item_ops.c
+++ b/fs/reiserfs/item_ops.c
@@ -275,7 +275,7 @@ static void indirect_print_item(struct item_head *ih, char *item)
275 int j; 275 int j;
276 __le32 *unp; 276 __le32 *unp;
277 __u32 prev = INT_MAX; 277 __u32 prev = INT_MAX;
278 int num; 278 int num = 0;
279 279
280 unp = (__le32 *) item; 280 unp = (__le32 *) item;
281 281
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index 5a9d2722fa0a..1b73529b8099 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -2227,6 +2227,9 @@ static int journal_read_transaction(struct super_block *p_s_sb,
2227 journal->j_start = cur_dblock - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb); 2227 journal->j_start = cur_dblock - SB_ONDISK_JOURNAL_1st_BLOCK(p_s_sb);
2228 journal->j_last_flush_trans_id = trans_id; 2228 journal->j_last_flush_trans_id = trans_id;
2229 journal->j_trans_id = trans_id + 1; 2229 journal->j_trans_id = trans_id + 1;
2230 /* check for trans_id overflow */
2231 if (journal->j_trans_id == 0)
2232 journal->j_trans_id = 10;
2230 brelse(c_bh); 2233 brelse(c_bh);
2231 brelse(d_bh); 2234 brelse(d_bh);
2232 kfree(log_blocks); 2235 kfree(log_blocks);
@@ -2450,6 +2453,9 @@ static int journal_read(struct super_block *p_s_sb)
2450 journal->j_start = le32_to_cpu(jh->j_first_unflushed_offset); 2453 journal->j_start = le32_to_cpu(jh->j_first_unflushed_offset);
2451 journal->j_trans_id = 2454 journal->j_trans_id =
2452 le32_to_cpu(jh->j_last_flush_trans_id) + 1; 2455 le32_to_cpu(jh->j_last_flush_trans_id) + 1;
2456 /* check for trans_id overflow */
2457 if (journal->j_trans_id == 0)
2458 journal->j_trans_id = 10;
2453 journal->j_last_flush_trans_id = 2459 journal->j_last_flush_trans_id =
2454 le32_to_cpu(jh->j_last_flush_trans_id); 2460 le32_to_cpu(jh->j_last_flush_trans_id);
2455 journal->j_mount_id = le32_to_cpu(jh->j_mount_id) + 1; 2461 journal->j_mount_id = le32_to_cpu(jh->j_mount_id) + 1;
@@ -3873,8 +3879,8 @@ static int do_journal_end(struct reiserfs_transaction_handle *th,
3873 int cur_write_start = 0; /* start index of current log write */ 3879 int cur_write_start = 0; /* start index of current log write */
3874 int old_start; 3880 int old_start;
3875 int i; 3881 int i;
3876 int flush = flags & FLUSH_ALL; 3882 int flush;
3877 int wait_on_commit = flags & WAIT; 3883 int wait_on_commit;
3878 struct reiserfs_journal_list *jl, *temp_jl; 3884 struct reiserfs_journal_list *jl, *temp_jl;
3879 struct list_head *entry, *safe; 3885 struct list_head *entry, *safe;
3880 unsigned long jindex; 3886 unsigned long jindex;
@@ -3884,6 +3890,13 @@ static int do_journal_end(struct reiserfs_transaction_handle *th,
3884 BUG_ON(th->t_refcount > 1); 3890 BUG_ON(th->t_refcount > 1);
3885 BUG_ON(!th->t_trans_id); 3891 BUG_ON(!th->t_trans_id);
3886 3892
3893 /* protect flush_older_commits from doing mistakes if the
3894 transaction ID counter gets overflowed. */
3895 if (th->t_trans_id == ~0UL)
3896 flags |= FLUSH_ALL | COMMIT_NOW | WAIT;
3897 flush = flags & FLUSH_ALL;
3898 wait_on_commit = flags & WAIT;
3899
3887 put_fs_excl(); 3900 put_fs_excl();
3888 current->journal_info = th->t_handle_save; 3901 current->journal_info = th->t_handle_save;
3889 reiserfs_check_lock_depth(p_s_sb, "journal end"); 3902 reiserfs_check_lock_depth(p_s_sb, "journal end");
@@ -4105,7 +4118,9 @@ static int do_journal_end(struct reiserfs_transaction_handle *th,
4105 journal->j_first = NULL; 4118 journal->j_first = NULL;
4106 journal->j_len = 0; 4119 journal->j_len = 0;
4107 journal->j_trans_start_time = 0; 4120 journal->j_trans_start_time = 0;
4108 journal->j_trans_id++; 4121 /* check for trans_id overflow */
4122 if (++journal->j_trans_id == 0)
4123 journal->j_trans_id = 10;
4109 journal->j_current_jl->j_trans_id = journal->j_trans_id; 4124 journal->j_current_jl->j_trans_id = journal->j_trans_id;
4110 journal->j_must_wait = 0; 4125 journal->j_must_wait = 0;
4111 journal->j_len_alloc = 0; 4126 journal->j_len_alloc = 0;
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
index e2d08d7bcffc..d2b25e1ba6e9 100644
--- a/fs/reiserfs/stree.c
+++ b/fs/reiserfs/stree.c
@@ -981,6 +981,8 @@ static inline int prepare_for_direntry_item(struct path *path,
981 return M_CUT; 981 return M_CUT;
982} 982}
983 983
984#define JOURNAL_FOR_FREE_BLOCK_AND_UPDATE_SD (2 * JOURNAL_PER_BALANCE_CNT + 1)
985
984/* If the path points to a directory or direct item, calculate mode and the size cut, for balance. 986/* If the path points to a directory or direct item, calculate mode and the size cut, for balance.
985 If the path points to an indirect item, remove some number of its unformatted nodes. 987 If the path points to an indirect item, remove some number of its unformatted nodes.
986 In case of file truncate calculate whether this item must be deleted/truncated or last 988 In case of file truncate calculate whether this item must be deleted/truncated or last
@@ -1020,148 +1022,79 @@ static char prepare_for_delete_or_cut(struct reiserfs_transaction_handle *th, st
1020 1022
1021 /* Case of an indirect item. */ 1023 /* Case of an indirect item. */
1022 { 1024 {
1023 int n_unfm_number, /* Number of the item unformatted nodes. */ 1025 int blk_size = p_s_sb->s_blocksize;
1024 n_counter, n_blk_size; 1026 struct item_head s_ih;
1025 __le32 *p_n_unfm_pointer; /* Pointer to the unformatted node number. */ 1027 int need_re_search;
1026 __u32 tmp; 1028 int delete = 0;
1027 struct item_head s_ih; /* Item header. */ 1029 int result = M_CUT;
1028 char c_mode; /* Returned mode of the balance. */ 1030 int pos = 0;
1029 int need_research; 1031
1030 1032 if ( n_new_file_length == max_reiserfs_offset (inode) ) {
1031 n_blk_size = p_s_sb->s_blocksize; 1033 /* prepare_for_delete_or_cut() is called by
1032 1034 * reiserfs_delete_item() */
1033 /* Search for the needed object indirect item until there are no unformatted nodes to be removed. */ 1035 n_new_file_length = 0;
1034 do { 1036 delete = 1;
1035 need_research = 0; 1037 }
1036 p_s_bh = PATH_PLAST_BUFFER(p_s_path); 1038
1037 /* Copy indirect item header to a temp variable. */ 1039 do {
1038 copy_item_head(&s_ih, PATH_PITEM_HEAD(p_s_path)); 1040 need_re_search = 0;
1039 /* Calculate number of unformatted nodes in this item. */ 1041 *p_n_cut_size = 0;
1040 n_unfm_number = I_UNFM_NUM(&s_ih); 1042 p_s_bh = PATH_PLAST_BUFFER(p_s_path);
1041 1043 copy_item_head(&s_ih, PATH_PITEM_HEAD(p_s_path));
1042 RFALSE(!is_indirect_le_ih(&s_ih) || !n_unfm_number || 1044 pos = I_UNFM_NUM(&s_ih);
1043 pos_in_item(p_s_path) + 1 != n_unfm_number,
1044 "PAP-5240: invalid item %h "
1045 "n_unfm_number = %d *p_n_pos_in_item = %d",
1046 &s_ih, n_unfm_number, pos_in_item(p_s_path));
1047
1048 /* Calculate balance mode and position in the item to remove unformatted nodes. */
1049 if (n_new_file_length == max_reiserfs_offset(inode)) { /* Case of delete. */
1050 pos_in_item(p_s_path) = 0;
1051 *p_n_cut_size = -(IH_SIZE + ih_item_len(&s_ih));
1052 c_mode = M_DELETE;
1053 } else { /* Case of truncate. */
1054 if (n_new_file_length < le_ih_k_offset(&s_ih)) {
1055 pos_in_item(p_s_path) = 0;
1056 *p_n_cut_size =
1057 -(IH_SIZE + ih_item_len(&s_ih));
1058 c_mode = M_DELETE; /* Delete this item. */
1059 } else {
1060 /* indirect item must be truncated starting from *p_n_pos_in_item-th position */
1061 pos_in_item(p_s_path) =
1062 (n_new_file_length + n_blk_size -
1063 le_ih_k_offset(&s_ih)) >> p_s_sb->
1064 s_blocksize_bits;
1065
1066 RFALSE(pos_in_item(p_s_path) >
1067 n_unfm_number,
1068 "PAP-5250: invalid position in the item");
1069
1070 /* Either convert last unformatted node of indirect item to direct item or increase
1071 its free space. */
1072 if (pos_in_item(p_s_path) ==
1073 n_unfm_number) {
1074 *p_n_cut_size = 0; /* Nothing to cut. */
1075 return M_CONVERT; /* Maybe convert last unformatted node to the direct item. */
1076 }
1077 /* Calculate size to cut. */
1078 *p_n_cut_size =
1079 -(ih_item_len(&s_ih) -
1080 pos_in_item(p_s_path) *
1081 UNFM_P_SIZE);
1082
1083 c_mode = M_CUT; /* Cut from this indirect item. */
1084 }
1085 }
1086 1045
1087 RFALSE(n_unfm_number <= pos_in_item(p_s_path), 1046 while (le_ih_k_offset (&s_ih) + (pos - 1) * blk_size > n_new_file_length) {
1088 "PAP-5260: invalid position in the indirect item"); 1047 __u32 *unfm, block;
1089
1090 /* pointers to be cut */
1091 n_unfm_number -= pos_in_item(p_s_path);
1092 /* Set pointer to the last unformatted node pointer that is to be cut. */
1093 p_n_unfm_pointer =
1094 (__le32 *) B_I_PITEM(p_s_bh,
1095 &s_ih) + I_UNFM_NUM(&s_ih) -
1096 1 - *p_n_removed;
1097
1098 /* We go through the unformatted nodes pointers of the indirect
1099 item and look for the unformatted nodes in the cache. If we
1100 found some of them we free it, zero corresponding indirect item
1101 entry and log buffer containing that indirect item. For this we
1102 need to prepare last path element for logging. If some
1103 unformatted node has b_count > 1 we must not free this
1104 unformatted node since it is in use. */
1105 reiserfs_prepare_for_journal(p_s_sb, p_s_bh, 1);
1106 // note: path could be changed, first line in for loop takes care
1107 // of it
1108 1048
1109 for (n_counter = *p_n_removed; 1049 /* Each unformatted block deletion may involve one additional
1110 n_counter < n_unfm_number; 1050 * bitmap block into the transaction, thereby the initial
1111 n_counter++, p_n_unfm_pointer--) { 1051 * journal space reservation might not be enough. */
1052 if (!delete && (*p_n_cut_size) != 0 &&
1053 reiserfs_transaction_free_space(th) < JOURNAL_FOR_FREE_BLOCK_AND_UPDATE_SD) {
1054 break;
1055 }
1112 1056
1113 cond_resched(); 1057 unfm = (__u32 *)B_I_PITEM(p_s_bh, &s_ih) + pos - 1;
1114 if (item_moved(&s_ih, p_s_path)) { 1058 block = get_block_num(unfm, 0);
1115 need_research = 1;
1116 break;
1117 }
1118 RFALSE(p_n_unfm_pointer <
1119 (__le32 *) B_I_PITEM(p_s_bh, &s_ih)
1120 || p_n_unfm_pointer >
1121 (__le32 *) B_I_PITEM(p_s_bh,
1122 &s_ih) +
1123 I_UNFM_NUM(&s_ih) - 1,
1124 "vs-5265: pointer out of range");
1125
1126 /* Hole, nothing to remove. */
1127 if (!get_block_num(p_n_unfm_pointer, 0)) {
1128 (*p_n_removed)++;
1129 continue;
1130 }
1131 1059
1132 (*p_n_removed)++; 1060 if (block != 0) {
1061 reiserfs_prepare_for_journal(p_s_sb, p_s_bh, 1);
1062 put_block_num(unfm, 0, 0);
1063 journal_mark_dirty (th, p_s_sb, p_s_bh);
1064 reiserfs_free_block(th, inode, block, 1);
1065 }
1133 1066
1134 tmp = get_block_num(p_n_unfm_pointer, 0); 1067 cond_resched();
1135 put_block_num(p_n_unfm_pointer, 0, 0);
1136 journal_mark_dirty(th, p_s_sb, p_s_bh);
1137 reiserfs_free_block(th, inode, tmp, 1);
1138 if (item_moved(&s_ih, p_s_path)) {
1139 need_research = 1;
1140 break;
1141 }
1142 }
1143 1068
1144 /* a trick. If the buffer has been logged, this 1069 if (item_moved (&s_ih, p_s_path)) {
1145 ** will do nothing. If we've broken the loop without 1070 need_re_search = 1;
1146 ** logging it, it will restore the buffer 1071 break;
1147 ** 1072 }
1148 */ 1073
1149 reiserfs_restore_prepared_buffer(p_s_sb, p_s_bh); 1074 pos --;
1150 1075 (*p_n_removed) ++;
1151 /* This loop can be optimized. */ 1076 (*p_n_cut_size) -= UNFM_P_SIZE;
1152 } while ((*p_n_removed < n_unfm_number || need_research) && 1077
1153 search_for_position_by_key(p_s_sb, p_s_item_key, 1078 if (pos == 0) {
1154 p_s_path) == 1079 (*p_n_cut_size) -= IH_SIZE;
1155 POSITION_FOUND); 1080 result = M_DELETE;
1156 1081 break;
1157 RFALSE(*p_n_removed < n_unfm_number, 1082 }
1158 "PAP-5310: indirect item is not found"); 1083 }
1159 RFALSE(item_moved(&s_ih, p_s_path), 1084 /* a trick. If the buffer has been logged, this will do nothing. If
1160 "after while, comp failed, retry"); 1085 ** we've broken the loop without logging it, it will restore the
1161 1086 ** buffer */
1162 if (c_mode == M_CUT) 1087 reiserfs_restore_prepared_buffer(p_s_sb, p_s_bh);
1163 pos_in_item(p_s_path) *= UNFM_P_SIZE; 1088 } while (need_re_search &&
1164 return c_mode; 1089 search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path) == POSITION_FOUND);
1090 pos_in_item(p_s_path) = pos * UNFM_P_SIZE;
1091
1092 if (*p_n_cut_size == 0) {
1093 /* Nothing were cut. maybe convert last unformatted node to the
1094 * direct item? */
1095 result = M_CONVERT;
1096 }
1097 return result;
1165 } 1098 }
1166} 1099}
1167 1100
@@ -1948,7 +1881,8 @@ int reiserfs_do_truncate(struct reiserfs_transaction_handle *th, struct inode *p
1948 ** sure the file is consistent before ending the current trans 1881 ** sure the file is consistent before ending the current trans
1949 ** and starting a new one 1882 ** and starting a new one
1950 */ 1883 */
1951 if (journal_transaction_should_end(th, th->t_blocks_allocated)) { 1884 if (journal_transaction_should_end(th, 0) ||
1885 reiserfs_transaction_free_space(th) <= JOURNAL_FOR_FREE_BLOCK_AND_UPDATE_SD) {
1952 int orig_len_alloc = th->t_blocks_allocated; 1886 int orig_len_alloc = th->t_blocks_allocated;
1953 decrement_counters_in_path(&s_search_path); 1887 decrement_counters_in_path(&s_search_path);
1954 1888
@@ -1962,7 +1896,7 @@ int reiserfs_do_truncate(struct reiserfs_transaction_handle *th, struct inode *p
1962 if (err) 1896 if (err)
1963 goto out; 1897 goto out;
1964 err = journal_begin(th, p_s_inode->i_sb, 1898 err = journal_begin(th, p_s_inode->i_sb,
1965 JOURNAL_PER_BALANCE_CNT * 6); 1899 JOURNAL_FOR_FREE_BLOCK_AND_UPDATE_SD + JOURNAL_PER_BALANCE_CNT * 4) ;
1966 if (err) 1900 if (err)
1967 goto out; 1901 goto out;
1968 reiserfs_update_inode_transaction(p_s_inode); 1902 reiserfs_update_inode_transaction(p_s_inode);
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 93e6ef9360e3..cae2abbc0c71 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -685,14 +685,14 @@ static const arg_desc_t logging_mode[] = {
685 (1 << REISERFS_DATA_ORDERED | 1 << REISERFS_DATA_WRITEBACK)}, 685 (1 << REISERFS_DATA_ORDERED | 1 << REISERFS_DATA_WRITEBACK)},
686 {"writeback", 1 << REISERFS_DATA_WRITEBACK, 686 {"writeback", 1 << REISERFS_DATA_WRITEBACK,
687 (1 << REISERFS_DATA_ORDERED | 1 << REISERFS_DATA_LOG)}, 687 (1 << REISERFS_DATA_ORDERED | 1 << REISERFS_DATA_LOG)},
688 {NULL, 0} 688 {.value = NULL}
689}; 689};
690 690
691/* possible values for -o barrier= */ 691/* possible values for -o barrier= */
692static const arg_desc_t barrier_mode[] = { 692static const arg_desc_t barrier_mode[] = {
693 {"none", 1 << REISERFS_BARRIER_NONE, 1 << REISERFS_BARRIER_FLUSH}, 693 {"none", 1 << REISERFS_BARRIER_NONE, 1 << REISERFS_BARRIER_FLUSH},
694 {"flush", 1 << REISERFS_BARRIER_FLUSH, 1 << REISERFS_BARRIER_NONE}, 694 {"flush", 1 << REISERFS_BARRIER_FLUSH, 1 << REISERFS_BARRIER_NONE},
695 {NULL, 0} 695 {.value = NULL}
696}; 696};
697 697
698/* possible values for "-o block-allocator=" and bits which are to be set in 698/* possible values for "-o block-allocator=" and bits which are to be set in
@@ -890,7 +890,7 @@ static int reiserfs_parse_options(struct super_block *s, char *options, /* strin
890 {"acl",.setmask = 1 << REISERFS_UNSUPPORTED_OPT}, 890 {"acl",.setmask = 1 << REISERFS_UNSUPPORTED_OPT},
891 {"noacl",.clrmask = 1 << REISERFS_UNSUPPORTED_OPT}, 891 {"noacl",.clrmask = 1 << REISERFS_UNSUPPORTED_OPT},
892#endif 892#endif
893 {"nolog",}, /* This is unsupported */ 893 {.option_name = "nolog"},
894 {"replayonly",.setmask = 1 << REPLAYONLY}, 894 {"replayonly",.setmask = 1 << REPLAYONLY},
895 {"block-allocator",.arg_required = 'a',.values = balloc}, 895 {"block-allocator",.arg_required = 'a',.values = balloc},
896 {"data",.arg_required = 'd',.values = logging_mode}, 896 {"data",.arg_required = 'd',.values = logging_mode},
@@ -908,7 +908,7 @@ static int reiserfs_parse_options(struct super_block *s, char *options, /* strin
908 {"grpjquota",.arg_required = 908 {"grpjquota",.arg_required =
909 'g' | (1 << REISERFS_OPT_ALLOWEMPTY),.values = NULL}, 909 'g' | (1 << REISERFS_OPT_ALLOWEMPTY),.values = NULL},
910 {"jqfmt",.arg_required = 'f',.values = NULL}, 910 {"jqfmt",.arg_required = 'f',.values = NULL},
911 {NULL,} 911 {.option_name = NULL}
912 }; 912 };
913 913
914 *blocks = 0; 914 *blocks = 0;
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c
index ab8894c3b9e5..58c418fbca2c 100644
--- a/fs/reiserfs/xattr_acl.c
+++ b/fs/reiserfs/xattr_acl.c
@@ -182,7 +182,7 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type)
182{ 182{
183 char *name, *value; 183 char *name, *value;
184 struct posix_acl *acl, **p_acl; 184 struct posix_acl *acl, **p_acl;
185 size_t size; 185 int size;
186 int retval; 186 int retval;
187 struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode); 187 struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode);
188 188
@@ -206,7 +206,7 @@ struct posix_acl *reiserfs_get_acl(struct inode *inode, int type)
206 return posix_acl_dup(*p_acl); 206 return posix_acl_dup(*p_acl);
207 207
208 size = reiserfs_xattr_get(inode, name, NULL, 0); 208 size = reiserfs_xattr_get(inode, name, NULL, 0);
209 if ((int)size < 0) { 209 if (size < 0) {
210 if (size == -ENODATA || size == -ENOSYS) { 210 if (size == -ENODATA || size == -ENOSYS) {
211 *p_acl = ERR_PTR(-ENODATA); 211 *p_acl = ERR_PTR(-ENODATA);
212 return NULL; 212 return NULL;
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c
index 44ed1d418b46..fdeabc0a34f7 100644
--- a/fs/smbfs/inode.c
+++ b/fs/smbfs/inode.c
@@ -217,7 +217,7 @@ smb_set_inode_attr(struct inode *inode, struct smb_fattr *fattr)
217 if (inode->i_mtime.tv_sec != last_time || inode->i_size != last_sz) { 217 if (inode->i_mtime.tv_sec != last_time || inode->i_size != last_sz) {
218 VERBOSE("%ld changed, old=%ld, new=%ld, oz=%ld, nz=%ld\n", 218 VERBOSE("%ld changed, old=%ld, new=%ld, oz=%ld, nz=%ld\n",
219 inode->i_ino, 219 inode->i_ino,
220 (long) last_time, (long) inode->i_mtime, 220 (long) last_time, (long) inode->i_mtime.tv_sec,
221 (long) last_sz, (long) inode->i_size); 221 (long) last_sz, (long) inode->i_size);
222 222
223 if (!S_ISDIR(inode->i_mode)) 223 if (!S_ISDIR(inode->i_mode))
diff --git a/fs/super.c b/fs/super.c
index 37554b876182..8743e9bbb297 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -55,11 +55,10 @@ DEFINE_SPINLOCK(sb_lock);
55 */ 55 */
56static struct super_block *alloc_super(void) 56static struct super_block *alloc_super(void)
57{ 57{
58 struct super_block *s = kmalloc(sizeof(struct super_block), GFP_USER); 58 struct super_block *s = kzalloc(sizeof(struct super_block), GFP_USER);
59 static struct super_operations default_op; 59 static struct super_operations default_op;
60 60
61 if (s) { 61 if (s) {
62 memset(s, 0, sizeof(struct super_block));
63 if (security_sb_alloc(s)) { 62 if (security_sb_alloc(s)) {
64 kfree(s); 63 kfree(s);
65 s = NULL; 64 s = NULL;
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index d04cff2273b6..81e0e8459af1 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -1341,13 +1341,11 @@ udf_update_inode(struct inode *inode, int do_sync)
1341 1341
1342 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET)) 1342 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_UID_FORGET))
1343 fe->uid = cpu_to_le32(-1); 1343 fe->uid = cpu_to_le32(-1);
1344 else if (inode->i_uid != UDF_SB(inode->i_sb)->s_uid) 1344 else fe->uid = cpu_to_le32(inode->i_uid);
1345 fe->uid = cpu_to_le32(inode->i_uid);
1346 1345
1347 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_FORGET)) 1346 if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_GID_FORGET))
1348 fe->gid = cpu_to_le32(-1); 1347 fe->gid = cpu_to_le32(-1);
1349 else if (inode->i_gid != UDF_SB(inode->i_sb)->s_gid) 1348 else fe->gid = cpu_to_le32(inode->i_gid);
1350 fe->gid = cpu_to_le32(inode->i_gid);
1351 1349
1352 udfperms = ((inode->i_mode & S_IRWXO) ) | 1350 udfperms = ((inode->i_mode & S_IRWXO) ) |
1353 ((inode->i_mode & S_IRWXG) << 2) | 1351 ((inode->i_mode & S_IRWXG) << 2) |