aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/compat.c100
-rw-r--r--fs/ecryptfs/inode.c2
-rw-r--r--fs/hostfs/hostfs_kern.c17
-rw-r--r--fs/partitions/check.c2
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
2243asmlinkage 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
2262asmlinkage 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
2288asmlinkage 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(&current->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 */
50static char *root_ino = "/"; 50static char *root_ino = "";
51static int append = 0; 51static 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)