diff options
Diffstat (limited to 'fs')
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 | ||
240 | struct Rcreate { | 240 | struct 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 | ||
366 | int v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, | 366 | int 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 | ||
369 | int v9fs_t_read(struct v9fs_session_info *v9ses, u32 fid, | 369 | int 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, | |||
372 | int v9fs_t_write(struct v9fs_session_info *v9ses, u32 fid, u64 offset, | 372 | int 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); |
375 | int 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 @@ | |||
1 | obj-$(CONFIG_9P_FS) := 9p2000.o | 1 | obj-$(CONFIG_9P_FS) := 9p.o |
2 | 2 | ||
3 | 9p2000-objs := \ | 3 | 9p-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 | ||
669 | struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode) | 668 | struct 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); | |||
39 | struct v9fs_fcall *v9fs_create_twalk(u32 fid, u32 newfid, u16 nwname, | 38 | struct v9fs_fcall *v9fs_create_twalk(u32 fid, u32 newfid, u16 nwname, |
40 | char **wnames); | 39 | char **wnames); |
41 | struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode); | 40 | struct v9fs_fcall *v9fs_create_topen(u32 fid, u8 mode); |
42 | struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode); | 41 | struct v9fs_fcall *v9fs_create_tcreate(u32 fid, char *name, u32 perm, u8 mode, |
42 | char *extension, int extended); | ||
43 | struct v9fs_fcall *v9fs_create_tread(u32 fid, u64 offset, u32 count); | 43 | struct v9fs_fcall *v9fs_create_tread(u32 fid, u64 offset, u32 count); |
44 | struct v9fs_fcall *v9fs_create_twrite(u32 fid, u64 offset, u32 count, | 44 | struct 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 | |||
159 | int v9fs_t_flush(struct v9fs_session_info *v9ses, u16 oldtag) | 157 | int 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 | ||
336 | int | 334 | int |
337 | v9fs_t_create(struct v9fs_session_info *v9ses, u32 fid, char *name, | 335 | v9fs_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 | |||
35 | static int | ||
36 | v9fs_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 | |||
60 | static int | ||
61 | v9fs_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 | |||
90 | static int | ||
91 | v9fs_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 | |||
122 | static int | ||
123 | v9fs_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 | |||
142 | static int | ||
143 | v9fs_printdata(char *buf, int buflen, u8 *data, int datalen) | ||
144 | { | ||
145 | return v9fs_dumpdata(buf, buflen, data, datalen<16?datalen:16); | ||
146 | } | ||
147 | |||
148 | int | ||
149 | v9fs_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 | ||
975 | static void v9fs_mux_put_tag(struct v9fs_mux_data *m, u16 tag) | 989 | static 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 | |||
43 | struct v9fs_trans_fd { | 47 | struct 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 | 59 | static int v9fs_fd_read(struct v9fs_transport *trans, void *v, int len) | |
56 | static 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 | 83 | static int v9fs_fd_write(struct v9fs_transport *trans, void *v, int len) | |
74 | static 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 | /** | 106 | static unsigned int |
93 | * v9fs_fd_init - initialize file descriptor transport | 107 | v9fs_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 | |||
100 | static int | ||
101 | v9fs_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 | |||
143 | static 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 | 168 | static 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 | |||
143 | static 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; | 179 | static 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 | ||
165 | static unsigned int | 204 | static int v9fs_tcp_init(struct v9fs_session_info *v9ses, const char *addr, |
166 | v9fs_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(); | 234 | static int |
180 | set_fs(get_ds()); | 235 | v9fs_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 | */ |
267 | static 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 | ||
203 | end: | 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 | |||
209 | struct v9fs_transport v9fs_trans_fd = { | 287 | struct 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 | ||
295 | struct 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 | |||
303 | struct 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 | |||
48 | struct 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 | |||
61 | static 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 | |||
93 | static 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 | |||
126 | static 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 | |||
155 | end: | ||
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 | |||
169 | static int | ||
170 | v9fs_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 | |||
234 | static int | ||
235 | v9fs_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 | |||
299 | static 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 | |||
320 | struct 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 | |||
328 | struct 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 | ||
54 | int v9fs_dentry_delete(struct dentry *dentry) | 53 | static 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 | ||
109 | destroy_vfid: | ||
110 | v9fs_fid_destroy(vfid); | ||
111 | |||
112 | clunk_fid: | 109 | clunk_fid: |
113 | v9fs_t_clunk(v9ses, fid); | 110 | v9fs_t_clunk(v9ses, fid); |
114 | 111 | ||
115 | put_fid: | 112 | put_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 | ||
257 | static int | 256 | static int |
258 | v9fs_create(struct v9fs_session_info *v9ses, u32 pfid, char *name, | 257 | v9fs_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 | ||
296 | error: | 295 | clunk_fid: |
296 | v9fs_t_clunk(v9ses, fid); | ||
297 | fid = V9FS_NOFID; | ||
298 | |||
299 | put_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 | ||
351 | struct inode * | 354 | static struct inode * |
352 | v9fs_inode_from_fid(struct v9fs_session_info *v9ses, u32 fid, | 355 | v9fs_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 | ||
1166 | error: | 1157 | error: |
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 | ||
264 | struct file_system_type v9fs_fs_type = { | 263 | struct 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, |
@@ -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(¤t->mm->mmap_sem); | 554 | down_write(¤t->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; |
786 | err_close: | ||
787 | sys_close(exec_fileno); | ||
788 | err: | ||
789 | return ret; | ||
755 | } | 790 | } |
756 | 791 | ||
757 | 792 | ||
@@ -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 | ||
1187 | struct bio_set *bioset_create(int bio_pool_size, int bvec_pool_size, int scale) | 1185 | struct 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 | } |
161 | EXPORT_SYMBOL(sync_blockdev); | 161 | EXPORT_SYMBOL(sync_blockdev); |
162 | 162 | ||
163 | /* | 163 | static 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 | */ | ||
168 | int 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 | */ | ||
182 | int 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 | ||
467 | struct cdev *cdev_alloc(void) | 465 | struct 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 | ||
326 | struct dentry * d_find_alias(struct inode *inode) | 326 | struct 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); |
851 | do_negative: | 856 | do_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; |
@@ -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 | ||
16 | static int nibblemap[] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0}; | 16 | static 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 | */ |
94 | DEFINE_MUTEX(iprune_mutex); | 94 | static 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 | ||
40 | static atomic_t inotify_cookie; | 40 | static atomic_t inotify_cookie; |
41 | static atomic_t inotify_watches; | ||
42 | 41 | ||
43 | static kmem_cache_t *watch_cachep; | 42 | static kmem_cache_t *watch_cachep; |
44 | static kmem_cache_t *event_cachep; | 43 | static 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 | */ | ||
386 | static 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 | */ | ||
395 | static 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 | */ |
488 | static inline int inotify_inode_watched(struct inode *inode) | 531 | void 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 | */ | ||
549 | void 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 | ||
40 | EXPORT_SYMBOL(journal_start); | 42 | EXPORT_SYMBOL(journal_start); |
41 | EXPORT_SYMBOL(journal_restart); | 43 | EXPORT_SYMBOL(journal_restart); |
@@ -111,18 +113,15 @@ static void commit_timeout(unsigned long __data) | |||
111 | 113 | ||
112 | static int kjournald(void *arg) | 114 | static 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 | ||
204 | end_loop: | 203 | end_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 | ||
213 | static void journal_start_thread(journal_t *journal) | 212 | static 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 | ||
255 | out_iput: | 255 | out_iput: |
@@ -273,19 +273,19 @@ out_no_bitmap: | |||
273 | 273 | ||
274 | out_no_map: | 274 | out_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 | ||
279 | out_no_fs: | 279 | out_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 | ||
287 | out_bad_hblock: | 287 | out_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 | ||
291 | out_bad_sb: | 291 | out_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 | ||
2630 | retry: | ||
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 | } |
@@ -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() |
@@ -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 | ||
490 | extern struct seq_operations slabstats_op; | ||
491 | static 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 | |||
508 | static 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 | |||
515 | static 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 | ||
490 | static int show_stat(struct seq_file *p, void *v) | 524 | static 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= */ |
692 | static const arg_desc_t barrier_mode[] = { | 692 | static 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 | */ |
56 | static struct super_block *alloc_super(void) | 56 | static 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) | |