diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/compat.c | 100 | ||||
-rw-r--r-- | fs/ecryptfs/inode.c | 2 | ||||
-rw-r--r-- | fs/hostfs/hostfs_kern.c | 17 | ||||
-rw-r--r-- | fs/partitions/check.c | 2 |
4 files changed, 113 insertions, 8 deletions
diff --git a/fs/compat.c b/fs/compat.c index 0ec70e3cee0a..040a8be38a48 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #include <linux/highmem.h> | 48 | #include <linux/highmem.h> |
49 | #include <linux/poll.h> | 49 | #include <linux/poll.h> |
50 | #include <linux/mm.h> | 50 | #include <linux/mm.h> |
51 | #include <linux/eventpoll.h> | ||
51 | 52 | ||
52 | #include <net/sock.h> /* siocdevprivate_ioctl */ | 53 | #include <net/sock.h> /* siocdevprivate_ioctl */ |
53 | 54 | ||
@@ -2235,3 +2236,102 @@ long asmlinkage compat_sys_nfsservctl(int cmd, void *notused, void *notused2) | |||
2235 | return sys_ni_syscall(); | 2236 | return sys_ni_syscall(); |
2236 | } | 2237 | } |
2237 | #endif | 2238 | #endif |
2239 | |||
2240 | #ifdef CONFIG_EPOLL | ||
2241 | |||
2242 | #ifdef CONFIG_HAS_COMPAT_EPOLL_EVENT | ||
2243 | asmlinkage long compat_sys_epoll_ctl(int epfd, int op, int fd, | ||
2244 | struct compat_epoll_event __user *event) | ||
2245 | { | ||
2246 | long err = 0; | ||
2247 | struct compat_epoll_event user; | ||
2248 | struct epoll_event __user *kernel = NULL; | ||
2249 | |||
2250 | if (event) { | ||
2251 | if (copy_from_user(&user, event, sizeof(user))) | ||
2252 | return -EFAULT; | ||
2253 | kernel = compat_alloc_user_space(sizeof(struct epoll_event)); | ||
2254 | err |= __put_user(user.events, &kernel->events); | ||
2255 | err |= __put_user(user.data, &kernel->data); | ||
2256 | } | ||
2257 | |||
2258 | return err ? err : sys_epoll_ctl(epfd, op, fd, kernel); | ||
2259 | } | ||
2260 | |||
2261 | |||
2262 | asmlinkage long compat_sys_epoll_wait(int epfd, | ||
2263 | struct compat_epoll_event __user *events, | ||
2264 | int maxevents, int timeout) | ||
2265 | { | ||
2266 | long i, ret, err = 0; | ||
2267 | struct epoll_event __user *kbuf; | ||
2268 | struct epoll_event ev; | ||
2269 | |||
2270 | if ((maxevents <= 0) || | ||
2271 | (maxevents > (INT_MAX / sizeof(struct epoll_event)))) | ||
2272 | return -EINVAL; | ||
2273 | kbuf = compat_alloc_user_space(sizeof(struct epoll_event) * maxevents); | ||
2274 | ret = sys_epoll_wait(epfd, kbuf, maxevents, timeout); | ||
2275 | for (i = 0; i < ret; i++) { | ||
2276 | err |= __get_user(ev.events, &kbuf[i].events); | ||
2277 | err |= __get_user(ev.data, &kbuf[i].data); | ||
2278 | err |= __put_user(ev.events, &events->events); | ||
2279 | err |= __put_user_unaligned(ev.data, &events->data); | ||
2280 | events++; | ||
2281 | } | ||
2282 | |||
2283 | return err ? -EFAULT: ret; | ||
2284 | } | ||
2285 | #endif /* CONFIG_HAS_COMPAT_EPOLL_EVENT */ | ||
2286 | |||
2287 | #ifdef TIF_RESTORE_SIGMASK | ||
2288 | asmlinkage long compat_sys_epoll_pwait(int epfd, | ||
2289 | struct compat_epoll_event __user *events, | ||
2290 | int maxevents, int timeout, | ||
2291 | const compat_sigset_t __user *sigmask, | ||
2292 | compat_size_t sigsetsize) | ||
2293 | { | ||
2294 | long err; | ||
2295 | compat_sigset_t csigmask; | ||
2296 | sigset_t ksigmask, sigsaved; | ||
2297 | |||
2298 | /* | ||
2299 | * If the caller wants a certain signal mask to be set during the wait, | ||
2300 | * we apply it here. | ||
2301 | */ | ||
2302 | if (sigmask) { | ||
2303 | if (sigsetsize != sizeof(compat_sigset_t)) | ||
2304 | return -EINVAL; | ||
2305 | if (copy_from_user(&csigmask, sigmask, sizeof(csigmask))) | ||
2306 | return -EFAULT; | ||
2307 | sigset_from_compat(&ksigmask, &csigmask); | ||
2308 | sigdelsetmask(&ksigmask, sigmask(SIGKILL) | sigmask(SIGSTOP)); | ||
2309 | sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved); | ||
2310 | } | ||
2311 | |||
2312 | #ifdef CONFIG_HAS_COMPAT_EPOLL_EVENT | ||
2313 | err = compat_sys_epoll_wait(epfd, events, maxevents, timeout); | ||
2314 | #else | ||
2315 | err = sys_epoll_wait(epfd, events, maxevents, timeout); | ||
2316 | #endif | ||
2317 | |||
2318 | /* | ||
2319 | * If we changed the signal mask, we need to restore the original one. | ||
2320 | * In case we've got a signal while waiting, we do not restore the | ||
2321 | * signal mask yet, and we allow do_signal() to deliver the signal on | ||
2322 | * the way back to userspace, before the signal mask is restored. | ||
2323 | */ | ||
2324 | if (sigmask) { | ||
2325 | if (err == -EINTR) { | ||
2326 | memcpy(¤t->saved_sigmask, &sigsaved, | ||
2327 | sizeof(sigsaved)); | ||
2328 | set_thread_flag(TIF_RESTORE_SIGMASK); | ||
2329 | } else | ||
2330 | sigprocmask(SIG_SETMASK, &sigsaved, NULL); | ||
2331 | } | ||
2332 | |||
2333 | return err; | ||
2334 | } | ||
2335 | #endif /* TIF_RESTORE_SIGMASK */ | ||
2336 | |||
2337 | #endif /* CONFIG_EPOLL */ | ||
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index e62f3fc7241e..1548be26b5e6 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -38,7 +38,7 @@ static struct dentry *lock_parent(struct dentry *dentry) | |||
38 | struct dentry *dir; | 38 | struct dentry *dir; |
39 | 39 | ||
40 | dir = dget(dentry->d_parent); | 40 | dir = dget(dentry->d_parent); |
41 | mutex_lock(&(dir->d_inode->i_mutex)); | 41 | mutex_lock_nested(&(dir->d_inode->i_mutex), I_MUTEX_PARENT); |
42 | return dir; | 42 | return dir; |
43 | } | 43 | } |
44 | 44 | ||
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index e965eb11d76f..9baf69773ed1 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
@@ -47,7 +47,7 @@ struct dentry_operations hostfs_dentry_ops = { | |||
47 | }; | 47 | }; |
48 | 48 | ||
49 | /* Changed in hostfs_args before the kernel starts running */ | 49 | /* Changed in hostfs_args before the kernel starts running */ |
50 | static char *root_ino = "/"; | 50 | static char *root_ino = ""; |
51 | static int append = 0; | 51 | static int append = 0; |
52 | 52 | ||
53 | #define HOSTFS_SUPER_MAGIC 0x00c0ffee | 53 | #define HOSTFS_SUPER_MAGIC 0x00c0ffee |
@@ -947,15 +947,17 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) | |||
947 | sb->s_magic = HOSTFS_SUPER_MAGIC; | 947 | sb->s_magic = HOSTFS_SUPER_MAGIC; |
948 | sb->s_op = &hostfs_sbops; | 948 | sb->s_op = &hostfs_sbops; |
949 | 949 | ||
950 | if((data == NULL) || (*data == '\0')) | 950 | /* NULL is printed as <NULL> by sprintf: avoid that. */ |
951 | data = root_ino; | 951 | if (data == NULL) |
952 | data = ""; | ||
952 | 953 | ||
953 | err = -ENOMEM; | 954 | err = -ENOMEM; |
954 | name = kmalloc(strlen(data) + 1, GFP_KERNEL); | 955 | name = kmalloc(strlen(root_ino) + 1 |
956 | + strlen(data) + 1, GFP_KERNEL); | ||
955 | if(name == NULL) | 957 | if(name == NULL) |
956 | goto out; | 958 | goto out; |
957 | 959 | ||
958 | strcpy(name, data); | 960 | sprintf(name, "%s/%s", root_ino, data); |
959 | 961 | ||
960 | root_inode = iget(sb, 0); | 962 | root_inode = iget(sb, 0); |
961 | if(root_inode == NULL) | 963 | if(root_inode == NULL) |
@@ -966,6 +968,9 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) | |||
966 | goto out_put; | 968 | goto out_put; |
967 | 969 | ||
968 | HOSTFS_I(root_inode)->host_filename = name; | 970 | HOSTFS_I(root_inode)->host_filename = name; |
971 | /* Avoid that in the error path, iput(root_inode) frees again name through | ||
972 | * hostfs_destroy_inode! */ | ||
973 | name = NULL; | ||
969 | 974 | ||
970 | err = -ENOMEM; | 975 | err = -ENOMEM; |
971 | sb->s_root = d_alloc_root(root_inode); | 976 | sb->s_root = d_alloc_root(root_inode); |
@@ -977,7 +982,7 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) | |||
977 | /* No iput in this case because the dput does that for us */ | 982 | /* No iput in this case because the dput does that for us */ |
978 | dput(sb->s_root); | 983 | dput(sb->s_root); |
979 | sb->s_root = NULL; | 984 | sb->s_root = NULL; |
980 | goto out_free; | 985 | goto out; |
981 | } | 986 | } |
982 | 987 | ||
983 | return(0); | 988 | return(0); |
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 22d38ffc9ef0..e46d237b10f9 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -180,7 +180,7 @@ check_partition(struct gendisk *hd, struct block_device *bdev) | |||
180 | } | 180 | } |
181 | if (res > 0) | 181 | if (res > 0) |
182 | return state; | 182 | return state; |
183 | if (!err) | 183 | if (err) |
184 | /* The partition is unrecognized. So report I/O errors if there were any */ | 184 | /* The partition is unrecognized. So report I/O errors if there were any */ |
185 | res = err; | 185 | res = err; |
186 | if (!res) | 186 | if (!res) |