diff options
Diffstat (limited to 'fs')
67 files changed, 736 insertions, 537 deletions
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h index 8ada4c5c5d70..6a82d39dc498 100644 --- a/fs/9p/v9fs_vfs.h +++ b/fs/9p/v9fs_vfs.h | |||
@@ -40,7 +40,6 @@ | |||
40 | extern struct file_system_type v9fs_fs_type; | 40 | extern struct file_system_type v9fs_fs_type; |
41 | extern const struct address_space_operations v9fs_addr_operations; | 41 | extern const struct address_space_operations v9fs_addr_operations; |
42 | extern const struct file_operations v9fs_file_operations; | 42 | extern const struct file_operations v9fs_file_operations; |
43 | extern const struct file_operations v9fs_cached_file_operations; | ||
44 | extern const struct file_operations v9fs_dir_operations; | 43 | extern const struct file_operations v9fs_dir_operations; |
45 | extern struct dentry_operations v9fs_dentry_operations; | 44 | extern struct dentry_operations v9fs_dentry_operations; |
46 | extern struct dentry_operations v9fs_cached_dentry_operations; | 45 | extern struct dentry_operations v9fs_cached_dentry_operations; |
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 653dfa5b2531..c7b677253843 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c | |||
@@ -42,6 +42,8 @@ | |||
42 | #include "v9fs_vfs.h" | 42 | #include "v9fs_vfs.h" |
43 | #include "fid.h" | 43 | #include "fid.h" |
44 | 44 | ||
45 | static const struct file_operations v9fs_cached_file_operations; | ||
46 | |||
45 | /** | 47 | /** |
46 | * v9fs_file_open - open a file (or directory) | 48 | * v9fs_file_open - open a file (or directory) |
47 | * @inode: inode to be opened | 49 | * @inode: inode to be opened |
@@ -245,7 +247,7 @@ v9fs_file_write(struct file *filp, const char __user * data, | |||
245 | return total; | 247 | return total; |
246 | } | 248 | } |
247 | 249 | ||
248 | const struct file_operations v9fs_cached_file_operations = { | 250 | static const struct file_operations v9fs_cached_file_operations = { |
249 | .llseek = generic_file_llseek, | 251 | .llseek = generic_file_llseek, |
250 | .read = do_sync_read, | 252 | .read = do_sync_read, |
251 | .aio_read = generic_file_aio_read, | 253 | .aio_read = generic_file_aio_read, |
@@ -136,7 +136,6 @@ static int aio_setup_ring(struct kioctx *ctx) | |||
136 | 0); | 136 | 0); |
137 | if (IS_ERR((void *)info->mmap_base)) { | 137 | if (IS_ERR((void *)info->mmap_base)) { |
138 | up_write(&ctx->mm->mmap_sem); | 138 | up_write(&ctx->mm->mmap_sem); |
139 | printk("mmap err: %ld\n", -info->mmap_base); | ||
140 | info->mmap_size = 0; | 139 | info->mmap_size = 0; |
141 | aio_free_ring(ctx); | 140 | aio_free_ring(ctx); |
142 | return -EAGAIN; | 141 | return -EAGAIN; |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 51db1182b27e..9cc4f0a8aaae 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -507,7 +507,7 @@ out: | |||
507 | #define INTERPRETER_ELF 2 | 507 | #define INTERPRETER_ELF 2 |
508 | 508 | ||
509 | #ifndef STACK_RND_MASK | 509 | #ifndef STACK_RND_MASK |
510 | #define STACK_RND_MASK 0x7ff /* with 4K pages 8MB of VA */ | 510 | #define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12)) /* 8MB of VA */ |
511 | #endif | 511 | #endif |
512 | 512 | ||
513 | static unsigned long randomize_stack_top(unsigned long stack_top) | 513 | static unsigned long randomize_stack_top(unsigned long stack_top) |
@@ -1704,7 +1704,10 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file) | |||
1704 | DUMP_SEEK(PAGE_SIZE); | 1704 | DUMP_SEEK(PAGE_SIZE); |
1705 | } else { | 1705 | } else { |
1706 | if (page == ZERO_PAGE(addr)) { | 1706 | if (page == ZERO_PAGE(addr)) { |
1707 | DUMP_SEEK(PAGE_SIZE); | 1707 | if (!dump_seek(file, PAGE_SIZE)) { |
1708 | page_cache_release(page); | ||
1709 | goto end_coredump; | ||
1710 | } | ||
1708 | } else { | 1711 | } else { |
1709 | void *kaddr; | 1712 | void *kaddr; |
1710 | flush_cache_page(vma, addr, | 1713 | flush_cache_page(vma, addr, |
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 5810aa1339fd..f3ddca4a387b 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
@@ -179,6 +179,8 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, | |||
179 | int executable_stack; | 179 | int executable_stack; |
180 | int retval, i; | 180 | int retval, i; |
181 | 181 | ||
182 | kdebug("____ LOAD %d ____", current->pid); | ||
183 | |||
182 | memset(&exec_params, 0, sizeof(exec_params)); | 184 | memset(&exec_params, 0, sizeof(exec_params)); |
183 | memset(&interp_params, 0, sizeof(interp_params)); | 185 | memset(&interp_params, 0, sizeof(interp_params)); |
184 | 186 | ||
@@ -941,8 +943,11 @@ static int elf_fdpic_map_file_constdisp_on_uclinux( | |||
941 | 943 | ||
942 | if (mm) { | 944 | if (mm) { |
943 | if (phdr->p_flags & PF_X) { | 945 | if (phdr->p_flags & PF_X) { |
944 | mm->start_code = seg->addr; | 946 | if (!mm->start_code) { |
945 | mm->end_code = seg->addr + phdr->p_memsz; | 947 | mm->start_code = seg->addr; |
948 | mm->end_code = seg->addr + | ||
949 | phdr->p_memsz; | ||
950 | } | ||
946 | } else if (!mm->start_data) { | 951 | } else if (!mm->start_data) { |
947 | mm->start_data = seg->addr; | 952 | mm->start_data = seg->addr; |
948 | #ifndef CONFIG_MMU | 953 | #ifndef CONFIG_MMU |
@@ -1123,8 +1128,10 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params, | |||
1123 | 1128 | ||
1124 | if (mm) { | 1129 | if (mm) { |
1125 | if (phdr->p_flags & PF_X) { | 1130 | if (phdr->p_flags & PF_X) { |
1126 | mm->start_code = maddr; | 1131 | if (!mm->start_code) { |
1127 | mm->end_code = maddr + phdr->p_memsz; | 1132 | mm->start_code = maddr; |
1133 | mm->end_code = maddr + phdr->p_memsz; | ||
1134 | } | ||
1128 | } else if (!mm->start_data) { | 1135 | } else if (!mm->start_data) { |
1129 | mm->start_data = maddr; | 1136 | mm->start_data = maddr; |
1130 | mm->end_data = maddr + phdr->p_memsz; | 1137 | mm->end_data = maddr + phdr->p_memsz; |
@@ -1473,8 +1480,8 @@ static int elf_fdpic_dump_segments(struct file *file, struct mm_struct *mm, | |||
1473 | DUMP_SEEK(file->f_pos + PAGE_SIZE); | 1480 | DUMP_SEEK(file->f_pos + PAGE_SIZE); |
1474 | } | 1481 | } |
1475 | else if (page == ZERO_PAGE(addr)) { | 1482 | else if (page == ZERO_PAGE(addr)) { |
1476 | DUMP_SEEK(file->f_pos + PAGE_SIZE); | ||
1477 | page_cache_release(page); | 1483 | page_cache_release(page); |
1484 | DUMP_SEEK(file->f_pos + PAGE_SIZE); | ||
1478 | } | 1485 | } |
1479 | else { | 1486 | else { |
1480 | void *kaddr; | 1487 | void *kaddr; |
diff --git a/fs/char_dev.c b/fs/char_dev.c index 78ced721554d..164a45cdaf5f 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c | |||
@@ -109,8 +109,6 @@ __register_chrdev_region(unsigned int major, unsigned int baseminor, | |||
109 | /* temporary */ | 109 | /* temporary */ |
110 | if (major == 0) { | 110 | if (major == 0) { |
111 | for (i = ARRAY_SIZE(chrdevs)-1; i > 0; i--) { | 111 | for (i = ARRAY_SIZE(chrdevs)-1; i > 0; i--) { |
112 | if (is_lanana_major(i)) | ||
113 | continue; | ||
114 | if (chrdevs[i] == NULL) | 112 | if (chrdevs[i] == NULL) |
115 | break; | 113 | break; |
116 | } | 114 | } |
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 6247628bdaed..5d1f4873d701 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
@@ -4,6 +4,12 @@ Fix mtime bouncing around from local idea of last write times to remote time. | |||
4 | Fix hang (in i_size_read) when simultaneous size update of same remote file | 4 | Fix hang (in i_size_read) when simultaneous size update of same remote file |
5 | on smp system corrupts sequence number. Do not reread unnecessarily partial page | 5 | on smp system corrupts sequence number. Do not reread unnecessarily partial page |
6 | (which we are about to overwrite anyway) when writing out file opened rw. | 6 | (which we are about to overwrite anyway) when writing out file opened rw. |
7 | When DOS attribute of file on non-Unix server's file changes on the server side | ||
8 | from read-only back to read-write, reflect this change in default file mode | ||
9 | (we had been leaving a file's mode read-only until the inode were reloaded). | ||
10 | Allow setting of attribute back to ATTR_NORMAL (removing readonly dos attribute | ||
11 | when archive dos attribute not set and we are changing mode back to writeable | ||
12 | on server which does not support the Unix Extensions). | ||
7 | 13 | ||
8 | Version 1.47 | 14 | Version 1.47 |
9 | ------------ | 15 | ------------ |
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 0efdf35aab2c..4d8948e8762c 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h | |||
@@ -220,7 +220,7 @@ | |||
220 | */ | 220 | */ |
221 | #define CIFS_NO_HANDLE 0xFFFF | 221 | #define CIFS_NO_HANDLE 0xFFFF |
222 | 222 | ||
223 | #define NO_CHANGE_64 0xFFFFFFFFFFFFFFFFULL | 223 | #define NO_CHANGE_64 cpu_to_le64(0xFFFFFFFFFFFFFFFFULL) |
224 | #define NO_CHANGE_32 0xFFFFFFFFUL | 224 | #define NO_CHANGE_32 0xFFFFFFFFUL |
225 | 225 | ||
226 | /* IPC$ in ASCII */ | 226 | /* IPC$ in ASCII */ |
@@ -1887,7 +1887,13 @@ typedef struct { | |||
1887 | calls including posix open | 1887 | calls including posix open |
1888 | and posix unlink */ | 1888 | and posix unlink */ |
1889 | #ifdef CONFIG_CIFS_POSIX | 1889 | #ifdef CONFIG_CIFS_POSIX |
1890 | #define CIFS_UNIX_CAP_MASK 0x0000003b | 1890 | /* Can not set pathnames cap yet until we send new posix create SMB since |
1891 | otherwise server can treat such handles opened with older ntcreatex | ||
1892 | (by a new client which knows how to send posix path ops) | ||
1893 | as non-posix handles (can affect write behavior with byte range locks. | ||
1894 | We can add back in POSIX_PATH_OPS cap when Posix Create/Mkdir finished */ | ||
1895 | /* #define CIFS_UNIX_CAP_MASK 0x0000003b */ | ||
1896 | #define CIFS_UNIX_CAP_MASK 0x0000001b | ||
1891 | #else | 1897 | #else |
1892 | #define CIFS_UNIX_CAP_MASK 0x00000013 | 1898 | #define CIFS_UNIX_CAP_MASK 0x00000013 |
1893 | #endif /* CONFIG_CIFS_POSIX */ | 1899 | #endif /* CONFIG_CIFS_POSIX */ |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 86b9dbbd8441..f414526e476a 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -494,6 +494,12 @@ int cifs_get_inode_info(struct inode **pinode, | |||
494 | mode e.g. 555 */ | 494 | mode e.g. 555 */ |
495 | if (cifsInfo->cifsAttrs & ATTR_READONLY) | 495 | if (cifsInfo->cifsAttrs & ATTR_READONLY) |
496 | inode->i_mode &= ~(S_IWUGO); | 496 | inode->i_mode &= ~(S_IWUGO); |
497 | else if ((inode->i_mode & S_IWUGO) == 0) | ||
498 | /* the ATTR_READONLY flag may have been */ | ||
499 | /* changed on server -- set any w bits */ | ||
500 | /* allowed by mnt_file_mode */ | ||
501 | inode->i_mode |= (S_IWUGO & | ||
502 | cifs_sb->mnt_file_mode); | ||
497 | /* BB add code here - | 503 | /* BB add code here - |
498 | validate if device or weird share or device type? */ | 504 | validate if device or weird share or device type? */ |
499 | } | 505 | } |
@@ -1190,6 +1196,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
1190 | struct cifsFileInfo *open_file = NULL; | 1196 | struct cifsFileInfo *open_file = NULL; |
1191 | FILE_BASIC_INFO time_buf; | 1197 | FILE_BASIC_INFO time_buf; |
1192 | int set_time = FALSE; | 1198 | int set_time = FALSE; |
1199 | int set_dosattr = FALSE; | ||
1193 | __u64 mode = 0xFFFFFFFFFFFFFFFFULL; | 1200 | __u64 mode = 0xFFFFFFFFFFFFFFFFULL; |
1194 | __u64 uid = 0xFFFFFFFFFFFFFFFFULL; | 1201 | __u64 uid = 0xFFFFFFFFFFFFFFFFULL; |
1195 | __u64 gid = 0xFFFFFFFFFFFFFFFFULL; | 1202 | __u64 gid = 0xFFFFFFFFFFFFFFFFULL; |
@@ -1326,15 +1333,23 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
1326 | else if (attrs->ia_valid & ATTR_MODE) { | 1333 | else if (attrs->ia_valid & ATTR_MODE) { |
1327 | rc = 0; | 1334 | rc = 0; |
1328 | if ((mode & S_IWUGO) == 0) /* not writeable */ { | 1335 | if ((mode & S_IWUGO) == 0) /* not writeable */ { |
1329 | if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) | 1336 | if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) { |
1337 | set_dosattr = TRUE; | ||
1330 | time_buf.Attributes = | 1338 | time_buf.Attributes = |
1331 | cpu_to_le32(cifsInode->cifsAttrs | | 1339 | cpu_to_le32(cifsInode->cifsAttrs | |
1332 | ATTR_READONLY); | 1340 | ATTR_READONLY); |
1341 | } | ||
1333 | } else if ((mode & S_IWUGO) == S_IWUGO) { | 1342 | } else if ((mode & S_IWUGO) == S_IWUGO) { |
1334 | if (cifsInode->cifsAttrs & ATTR_READONLY) | 1343 | if (cifsInode->cifsAttrs & ATTR_READONLY) { |
1344 | set_dosattr = TRUE; | ||
1335 | time_buf.Attributes = | 1345 | time_buf.Attributes = |
1336 | cpu_to_le32(cifsInode->cifsAttrs & | 1346 | cpu_to_le32(cifsInode->cifsAttrs & |
1337 | (~ATTR_READONLY)); | 1347 | (~ATTR_READONLY)); |
1348 | /* Windows ignores set to zero */ | ||
1349 | if(time_buf.Attributes == 0) | ||
1350 | time_buf.Attributes |= | ||
1351 | cpu_to_le32(ATTR_NORMAL); | ||
1352 | } | ||
1338 | } | 1353 | } |
1339 | /* BB to be implemented - | 1354 | /* BB to be implemented - |
1340 | via Windows security descriptors or streams */ | 1355 | via Windows security descriptors or streams */ |
@@ -1372,7 +1387,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
1372 | } else | 1387 | } else |
1373 | time_buf.ChangeTime = 0; | 1388 | time_buf.ChangeTime = 0; |
1374 | 1389 | ||
1375 | if (set_time || time_buf.Attributes) { | 1390 | if (set_time || set_dosattr) { |
1376 | time_buf.CreationTime = 0; /* do not change */ | 1391 | time_buf.CreationTime = 0; /* do not change */ |
1377 | /* In the future we should experiment - try setting timestamps | 1392 | /* In the future we should experiment - try setting timestamps |
1378 | via Handle (SetFileInfo) instead of by path */ | 1393 | via Handle (SetFileInfo) instead of by path */ |
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 44cfb528797d..2a374d5215ab 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -219,6 +219,10 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, | |||
219 | tmp_inode->i_mode |= S_IFREG; | 219 | tmp_inode->i_mode |= S_IFREG; |
220 | if (attr & ATTR_READONLY) | 220 | if (attr & ATTR_READONLY) |
221 | tmp_inode->i_mode &= ~(S_IWUGO); | 221 | tmp_inode->i_mode &= ~(S_IWUGO); |
222 | else if ((tmp_inode->i_mode & S_IWUGO) == 0) | ||
223 | /* the ATTR_READONLY flag may have been changed on */ | ||
224 | /* server -- set any w bits allowed by mnt_file_mode */ | ||
225 | tmp_inode->i_mode |= (S_IWUGO & cifs_sb->mnt_file_mode); | ||
222 | } /* could add code here - to validate if device or weird share type? */ | 226 | } /* could add code here - to validate if device or weird share type? */ |
223 | 227 | ||
224 | /* can not fill in nlink here as in qpathinfo version and Unx search */ | 228 | /* can not fill in nlink here as in qpathinfo version and Unx search */ |
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/compat_ioctl.c b/fs/compat_ioctl.c index c81c958b3e1d..8b1c5d8bf4ef 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
@@ -2553,11 +2553,15 @@ HANDLE_IOCTL(I2C_RDWR, do_i2c_rdwr_ioctl) | |||
2553 | HANDLE_IOCTL(I2C_SMBUS, do_i2c_smbus_ioctl) | 2553 | HANDLE_IOCTL(I2C_SMBUS, do_i2c_smbus_ioctl) |
2554 | /* wireless */ | 2554 | /* wireless */ |
2555 | HANDLE_IOCTL(SIOCGIWRANGE, do_wireless_ioctl) | 2555 | HANDLE_IOCTL(SIOCGIWRANGE, do_wireless_ioctl) |
2556 | HANDLE_IOCTL(SIOCGIWPRIV, do_wireless_ioctl) | ||
2557 | HANDLE_IOCTL(SIOCGIWSTATS, do_wireless_ioctl) | ||
2556 | HANDLE_IOCTL(SIOCSIWSPY, do_wireless_ioctl) | 2558 | HANDLE_IOCTL(SIOCSIWSPY, do_wireless_ioctl) |
2557 | HANDLE_IOCTL(SIOCGIWSPY, do_wireless_ioctl) | 2559 | HANDLE_IOCTL(SIOCGIWSPY, do_wireless_ioctl) |
2558 | HANDLE_IOCTL(SIOCSIWTHRSPY, do_wireless_ioctl) | 2560 | HANDLE_IOCTL(SIOCSIWTHRSPY, do_wireless_ioctl) |
2559 | HANDLE_IOCTL(SIOCGIWTHRSPY, do_wireless_ioctl) | 2561 | HANDLE_IOCTL(SIOCGIWTHRSPY, do_wireless_ioctl) |
2562 | HANDLE_IOCTL(SIOCSIWMLME, do_wireless_ioctl) | ||
2560 | HANDLE_IOCTL(SIOCGIWAPLIST, do_wireless_ioctl) | 2563 | HANDLE_IOCTL(SIOCGIWAPLIST, do_wireless_ioctl) |
2564 | HANDLE_IOCTL(SIOCSIWSCAN, do_wireless_ioctl) | ||
2561 | HANDLE_IOCTL(SIOCGIWSCAN, do_wireless_ioctl) | 2565 | HANDLE_IOCTL(SIOCGIWSCAN, do_wireless_ioctl) |
2562 | HANDLE_IOCTL(SIOCSIWESSID, do_wireless_ioctl) | 2566 | HANDLE_IOCTL(SIOCSIWESSID, do_wireless_ioctl) |
2563 | HANDLE_IOCTL(SIOCGIWESSID, do_wireless_ioctl) | 2567 | HANDLE_IOCTL(SIOCGIWESSID, do_wireless_ioctl) |
@@ -2565,6 +2569,11 @@ HANDLE_IOCTL(SIOCSIWNICKN, do_wireless_ioctl) | |||
2565 | HANDLE_IOCTL(SIOCGIWNICKN, do_wireless_ioctl) | 2569 | HANDLE_IOCTL(SIOCGIWNICKN, do_wireless_ioctl) |
2566 | HANDLE_IOCTL(SIOCSIWENCODE, do_wireless_ioctl) | 2570 | HANDLE_IOCTL(SIOCSIWENCODE, do_wireless_ioctl) |
2567 | HANDLE_IOCTL(SIOCGIWENCODE, do_wireless_ioctl) | 2571 | HANDLE_IOCTL(SIOCGIWENCODE, do_wireless_ioctl) |
2572 | HANDLE_IOCTL(SIOCSIWGENIE, do_wireless_ioctl) | ||
2573 | HANDLE_IOCTL(SIOCGIWGENIE, do_wireless_ioctl) | ||
2574 | HANDLE_IOCTL(SIOCSIWENCODEEXT, do_wireless_ioctl) | ||
2575 | HANDLE_IOCTL(SIOCGIWENCODEEXT, do_wireless_ioctl) | ||
2576 | HANDLE_IOCTL(SIOCSIWPMKSA, do_wireless_ioctl) | ||
2568 | HANDLE_IOCTL(SIOCSIFBR, old_bridge_ioctl) | 2577 | HANDLE_IOCTL(SIOCSIFBR, old_bridge_ioctl) |
2569 | HANDLE_IOCTL(SIOCGIFBR, old_bridge_ioctl) | 2578 | HANDLE_IOCTL(SIOCGIFBR, old_bridge_ioctl) |
2570 | HANDLE_IOCTL(RTC_IRQP_READ32, rtc_ioctl) | 2579 | HANDLE_IOCTL(RTC_IRQP_READ32, rtc_ioctl) |
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 34750d5e4ff2..5e6e37e58f36 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c | |||
@@ -1141,25 +1141,22 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys) | |||
1141 | 1141 | ||
1142 | err = -ENOMEM; | 1142 | err = -ENOMEM; |
1143 | dentry = d_alloc(configfs_sb->s_root, &name); | 1143 | dentry = d_alloc(configfs_sb->s_root, &name); |
1144 | if (!dentry) | 1144 | if (dentry) { |
1145 | goto out_release; | 1145 | d_add(dentry, NULL); |
1146 | |||
1147 | d_add(dentry, NULL); | ||
1148 | 1146 | ||
1149 | err = configfs_attach_group(sd->s_element, &group->cg_item, | 1147 | err = configfs_attach_group(sd->s_element, &group->cg_item, |
1150 | dentry); | 1148 | dentry); |
1151 | if (!err) | 1149 | if (err) { |
1152 | dentry = NULL; | 1150 | d_delete(dentry); |
1153 | else | 1151 | dput(dentry); |
1154 | d_delete(dentry); | 1152 | } |
1153 | } | ||
1155 | 1154 | ||
1156 | mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex); | 1155 | mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex); |
1157 | 1156 | ||
1158 | if (dentry) { | 1157 | if (err) { |
1159 | dput(dentry); | 1158 | unlink_group(group); |
1160 | out_release: | 1159 | configfs_release_fs(); |
1161 | unlink_group(group); | ||
1162 | configfs_release_fs(); | ||
1163 | } | 1160 | } |
1164 | 1161 | ||
1165 | return err; | 1162 | return err; |
diff --git a/fs/dlm/user.c b/fs/dlm/user.c index 40db61dc95f2..3870150b83a4 100644 --- a/fs/dlm/user.c +++ b/fs/dlm/user.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include "lockspace.h" | 22 | #include "lockspace.h" |
23 | #include "lock.h" | 23 | #include "lock.h" |
24 | #include "lvb_table.h" | 24 | #include "lvb_table.h" |
25 | #include "user.h" | ||
25 | 26 | ||
26 | static const char *name_prefix="dlm"; | 27 | static const char *name_prefix="dlm"; |
27 | static struct miscdevice ctl_device; | 28 | static struct miscdevice ctl_device; |
diff --git a/fs/ecryptfs/dentry.c b/fs/ecryptfs/dentry.c index 329efcd3d8c9..cb20b964419f 100644 --- a/fs/ecryptfs/dentry.c +++ b/fs/ecryptfs/dentry.c | |||
@@ -78,18 +78,13 @@ struct kmem_cache *ecryptfs_dentry_info_cache; | |||
78 | */ | 78 | */ |
79 | static void ecryptfs_d_release(struct dentry *dentry) | 79 | static void ecryptfs_d_release(struct dentry *dentry) |
80 | { | 80 | { |
81 | struct dentry *lower_dentry; | 81 | if (ecryptfs_dentry_to_private(dentry)) { |
82 | 82 | if (ecryptfs_dentry_to_lower(dentry)) { | |
83 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 83 | mntput(ecryptfs_dentry_to_lower_mnt(dentry)); |
84 | if (ecryptfs_dentry_to_private(dentry)) | 84 | dput(ecryptfs_dentry_to_lower(dentry)); |
85 | } | ||
85 | kmem_cache_free(ecryptfs_dentry_info_cache, | 86 | kmem_cache_free(ecryptfs_dentry_info_cache, |
86 | ecryptfs_dentry_to_private(dentry)); | 87 | ecryptfs_dentry_to_private(dentry)); |
87 | if (lower_dentry) { | ||
88 | struct vfsmount *lower_mnt = | ||
89 | ecryptfs_dentry_to_lower_mnt(dentry); | ||
90 | |||
91 | mntput(lower_mnt); | ||
92 | dput(lower_dentry); | ||
93 | } | 88 | } |
94 | return; | 89 | return; |
95 | } | 90 | } |
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/ext3/inode.c b/fs/ext3/inode.c index 8a824f4ce5c6..a5b150f7e8a2 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -1148,102 +1148,37 @@ static int do_journal_get_write_access(handle_t *handle, | |||
1148 | return ext3_journal_get_write_access(handle, bh); | 1148 | return ext3_journal_get_write_access(handle, bh); |
1149 | } | 1149 | } |
1150 | 1150 | ||
1151 | /* | ||
1152 | * The idea of this helper function is following: | ||
1153 | * if prepare_write has allocated some blocks, but not all of them, the | ||
1154 | * transaction must include the content of the newly allocated blocks. | ||
1155 | * This content is expected to be set to zeroes by block_prepare_write(). | ||
1156 | * 2006/10/14 SAW | ||
1157 | */ | ||
1158 | static int ext3_prepare_failure(struct file *file, struct page *page, | ||
1159 | unsigned from, unsigned to) | ||
1160 | { | ||
1161 | struct address_space *mapping; | ||
1162 | struct buffer_head *bh, *head, *next; | ||
1163 | unsigned block_start, block_end; | ||
1164 | unsigned blocksize; | ||
1165 | int ret; | ||
1166 | handle_t *handle = ext3_journal_current_handle(); | ||
1167 | |||
1168 | mapping = page->mapping; | ||
1169 | if (ext3_should_writeback_data(mapping->host)) { | ||
1170 | /* optimization: no constraints about data */ | ||
1171 | skip: | ||
1172 | return ext3_journal_stop(handle); | ||
1173 | } | ||
1174 | |||
1175 | head = page_buffers(page); | ||
1176 | blocksize = head->b_size; | ||
1177 | for ( bh = head, block_start = 0; | ||
1178 | bh != head || !block_start; | ||
1179 | block_start = block_end, bh = next) | ||
1180 | { | ||
1181 | next = bh->b_this_page; | ||
1182 | block_end = block_start + blocksize; | ||
1183 | if (block_end <= from) | ||
1184 | continue; | ||
1185 | if (block_start >= to) { | ||
1186 | block_start = to; | ||
1187 | break; | ||
1188 | } | ||
1189 | if (!buffer_mapped(bh)) | ||
1190 | /* prepare_write failed on this bh */ | ||
1191 | break; | ||
1192 | if (ext3_should_journal_data(mapping->host)) { | ||
1193 | ret = do_journal_get_write_access(handle, bh); | ||
1194 | if (ret) { | ||
1195 | ext3_journal_stop(handle); | ||
1196 | return ret; | ||
1197 | } | ||
1198 | } | ||
1199 | /* | ||
1200 | * block_start here becomes the first block where the current iteration | ||
1201 | * of prepare_write failed. | ||
1202 | */ | ||
1203 | } | ||
1204 | if (block_start <= from) | ||
1205 | goto skip; | ||
1206 | |||
1207 | /* commit allocated and zeroed buffers */ | ||
1208 | return mapping->a_ops->commit_write(file, page, from, block_start); | ||
1209 | } | ||
1210 | |||
1211 | static int ext3_prepare_write(struct file *file, struct page *page, | 1151 | static int ext3_prepare_write(struct file *file, struct page *page, |
1212 | unsigned from, unsigned to) | 1152 | unsigned from, unsigned to) |
1213 | { | 1153 | { |
1214 | struct inode *inode = page->mapping->host; | 1154 | struct inode *inode = page->mapping->host; |
1215 | int ret, ret2; | 1155 | int ret, needed_blocks = ext3_writepage_trans_blocks(inode); |
1216 | int needed_blocks = ext3_writepage_trans_blocks(inode); | ||
1217 | handle_t *handle; | 1156 | handle_t *handle; |
1218 | int retries = 0; | 1157 | int retries = 0; |
1219 | 1158 | ||
1220 | retry: | 1159 | retry: |
1221 | handle = ext3_journal_start(inode, needed_blocks); | 1160 | handle = ext3_journal_start(inode, needed_blocks); |
1222 | if (IS_ERR(handle)) | 1161 | if (IS_ERR(handle)) { |
1223 | return PTR_ERR(handle); | 1162 | ret = PTR_ERR(handle); |
1163 | goto out; | ||
1164 | } | ||
1224 | if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode)) | 1165 | if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode)) |
1225 | ret = nobh_prepare_write(page, from, to, ext3_get_block); | 1166 | ret = nobh_prepare_write(page, from, to, ext3_get_block); |
1226 | else | 1167 | else |
1227 | ret = block_prepare_write(page, from, to, ext3_get_block); | 1168 | ret = block_prepare_write(page, from, to, ext3_get_block); |
1228 | if (ret) | 1169 | if (ret) |
1229 | goto failure; | 1170 | goto prepare_write_failed; |
1230 | 1171 | ||
1231 | if (ext3_should_journal_data(inode)) { | 1172 | if (ext3_should_journal_data(inode)) { |
1232 | ret = walk_page_buffers(handle, page_buffers(page), | 1173 | ret = walk_page_buffers(handle, page_buffers(page), |
1233 | from, to, NULL, do_journal_get_write_access); | 1174 | from, to, NULL, do_journal_get_write_access); |
1234 | if (ret) | ||
1235 | /* fatal error, just put the handle and return */ | ||
1236 | journal_stop(handle); | ||
1237 | } | 1175 | } |
1238 | return ret; | 1176 | prepare_write_failed: |
1239 | 1177 | if (ret) | |
1240 | failure: | 1178 | ext3_journal_stop(handle); |
1241 | ret2 = ext3_prepare_failure(file, page, from, to); | ||
1242 | if (ret2 < 0) | ||
1243 | return ret2; | ||
1244 | if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries)) | 1179 | if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries)) |
1245 | goto retry; | 1180 | goto retry; |
1246 | /* retry number exceeded, or other error like -EDQUOT */ | 1181 | out: |
1247 | return ret; | 1182 | return ret; |
1248 | } | 1183 | } |
1249 | 1184 | ||
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c index 12f7dda1232c..f58cbb26323e 100644 --- a/fs/ext3/xattr.c +++ b/fs/ext3/xattr.c | |||
@@ -495,7 +495,8 @@ ext3_xattr_release_block(handle_t *handle, struct inode *inode, | |||
495 | BHDR(bh)->h_refcount = cpu_to_le32( | 495 | BHDR(bh)->h_refcount = cpu_to_le32( |
496 | le32_to_cpu(BHDR(bh)->h_refcount) - 1); | 496 | le32_to_cpu(BHDR(bh)->h_refcount) - 1); |
497 | error = ext3_journal_dirty_metadata(handle, bh); | 497 | error = ext3_journal_dirty_metadata(handle, bh); |
498 | handle->h_sync = 1; | 498 | if (IS_SYNC(inode)) |
499 | handle->h_sync = 1; | ||
499 | DQUOT_FREE_BLOCK(inode, 1); | 500 | DQUOT_FREE_BLOCK(inode, 1); |
500 | ea_bdebug(bh, "refcount now=%d; releasing", | 501 | ea_bdebug(bh, "refcount now=%d; releasing", |
501 | le32_to_cpu(BHDR(bh)->h_refcount)); | 502 | le32_to_cpu(BHDR(bh)->h_refcount)); |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index fbff4b9e122a..810b6d6474bf 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -1147,102 +1147,37 @@ static int do_journal_get_write_access(handle_t *handle, | |||
1147 | return ext4_journal_get_write_access(handle, bh); | 1147 | return ext4_journal_get_write_access(handle, bh); |
1148 | } | 1148 | } |
1149 | 1149 | ||
1150 | /* | ||
1151 | * The idea of this helper function is following: | ||
1152 | * if prepare_write has allocated some blocks, but not all of them, the | ||
1153 | * transaction must include the content of the newly allocated blocks. | ||
1154 | * This content is expected to be set to zeroes by block_prepare_write(). | ||
1155 | * 2006/10/14 SAW | ||
1156 | */ | ||
1157 | static int ext4_prepare_failure(struct file *file, struct page *page, | ||
1158 | unsigned from, unsigned to) | ||
1159 | { | ||
1160 | struct address_space *mapping; | ||
1161 | struct buffer_head *bh, *head, *next; | ||
1162 | unsigned block_start, block_end; | ||
1163 | unsigned blocksize; | ||
1164 | int ret; | ||
1165 | handle_t *handle = ext4_journal_current_handle(); | ||
1166 | |||
1167 | mapping = page->mapping; | ||
1168 | if (ext4_should_writeback_data(mapping->host)) { | ||
1169 | /* optimization: no constraints about data */ | ||
1170 | skip: | ||
1171 | return ext4_journal_stop(handle); | ||
1172 | } | ||
1173 | |||
1174 | head = page_buffers(page); | ||
1175 | blocksize = head->b_size; | ||
1176 | for ( bh = head, block_start = 0; | ||
1177 | bh != head || !block_start; | ||
1178 | block_start = block_end, bh = next) | ||
1179 | { | ||
1180 | next = bh->b_this_page; | ||
1181 | block_end = block_start + blocksize; | ||
1182 | if (block_end <= from) | ||
1183 | continue; | ||
1184 | if (block_start >= to) { | ||
1185 | block_start = to; | ||
1186 | break; | ||
1187 | } | ||
1188 | if (!buffer_mapped(bh)) | ||
1189 | /* prepare_write failed on this bh */ | ||
1190 | break; | ||
1191 | if (ext4_should_journal_data(mapping->host)) { | ||
1192 | ret = do_journal_get_write_access(handle, bh); | ||
1193 | if (ret) { | ||
1194 | ext4_journal_stop(handle); | ||
1195 | return ret; | ||
1196 | } | ||
1197 | } | ||
1198 | /* | ||
1199 | * block_start here becomes the first block where the current iteration | ||
1200 | * of prepare_write failed. | ||
1201 | */ | ||
1202 | } | ||
1203 | if (block_start <= from) | ||
1204 | goto skip; | ||
1205 | |||
1206 | /* commit allocated and zeroed buffers */ | ||
1207 | return mapping->a_ops->commit_write(file, page, from, block_start); | ||
1208 | } | ||
1209 | |||
1210 | static int ext4_prepare_write(struct file *file, struct page *page, | 1150 | static int ext4_prepare_write(struct file *file, struct page *page, |
1211 | unsigned from, unsigned to) | 1151 | unsigned from, unsigned to) |
1212 | { | 1152 | { |
1213 | struct inode *inode = page->mapping->host; | 1153 | struct inode *inode = page->mapping->host; |
1214 | int ret, ret2; | 1154 | int ret, needed_blocks = ext4_writepage_trans_blocks(inode); |
1215 | int needed_blocks = ext4_writepage_trans_blocks(inode); | ||
1216 | handle_t *handle; | 1155 | handle_t *handle; |
1217 | int retries = 0; | 1156 | int retries = 0; |
1218 | 1157 | ||
1219 | retry: | 1158 | retry: |
1220 | handle = ext4_journal_start(inode, needed_blocks); | 1159 | handle = ext4_journal_start(inode, needed_blocks); |
1221 | if (IS_ERR(handle)) | 1160 | if (IS_ERR(handle)) { |
1222 | return PTR_ERR(handle); | 1161 | ret = PTR_ERR(handle); |
1162 | goto out; | ||
1163 | } | ||
1223 | if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode)) | 1164 | if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode)) |
1224 | ret = nobh_prepare_write(page, from, to, ext4_get_block); | 1165 | ret = nobh_prepare_write(page, from, to, ext4_get_block); |
1225 | else | 1166 | else |
1226 | ret = block_prepare_write(page, from, to, ext4_get_block); | 1167 | ret = block_prepare_write(page, from, to, ext4_get_block); |
1227 | if (ret) | 1168 | if (ret) |
1228 | goto failure; | 1169 | goto prepare_write_failed; |
1229 | 1170 | ||
1230 | if (ext4_should_journal_data(inode)) { | 1171 | if (ext4_should_journal_data(inode)) { |
1231 | ret = walk_page_buffers(handle, page_buffers(page), | 1172 | ret = walk_page_buffers(handle, page_buffers(page), |
1232 | from, to, NULL, do_journal_get_write_access); | 1173 | from, to, NULL, do_journal_get_write_access); |
1233 | if (ret) | ||
1234 | /* fatal error, just put the handle and return */ | ||
1235 | ext4_journal_stop(handle); | ||
1236 | } | 1174 | } |
1237 | return ret; | 1175 | prepare_write_failed: |
1238 | 1176 | if (ret) | |
1239 | failure: | 1177 | ext4_journal_stop(handle); |
1240 | ret2 = ext4_prepare_failure(file, page, from, to); | ||
1241 | if (ret2 < 0) | ||
1242 | return ret2; | ||
1243 | if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) | 1178 | if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) |
1244 | goto retry; | 1179 | goto retry; |
1245 | /* retry number exceeded, or other error like -EDQUOT */ | 1180 | out: |
1246 | return ret; | 1181 | return ret; |
1247 | } | 1182 | } |
1248 | 1183 | ||
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 406bf61ed510..8890eba1db52 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -195,7 +195,7 @@ static struct dentry_operations fuse_dentry_operations = { | |||
195 | .d_revalidate = fuse_dentry_revalidate, | 195 | .d_revalidate = fuse_dentry_revalidate, |
196 | }; | 196 | }; |
197 | 197 | ||
198 | static int valid_mode(int m) | 198 | int fuse_valid_type(int m) |
199 | { | 199 | { |
200 | return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) || | 200 | return S_ISREG(m) || S_ISDIR(m) || S_ISLNK(m) || S_ISCHR(m) || |
201 | S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m); | 201 | S_ISBLK(m) || S_ISFIFO(m) || S_ISSOCK(m); |
@@ -248,7 +248,8 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry, | |||
248 | fuse_put_request(fc, req); | 248 | fuse_put_request(fc, req); |
249 | /* Zero nodeid is same as -ENOENT, but with valid timeout */ | 249 | /* Zero nodeid is same as -ENOENT, but with valid timeout */ |
250 | if (!err && outarg.nodeid && | 250 | if (!err && outarg.nodeid && |
251 | (invalid_nodeid(outarg.nodeid) || !valid_mode(outarg.attr.mode))) | 251 | (invalid_nodeid(outarg.nodeid) || |
252 | !fuse_valid_type(outarg.attr.mode))) | ||
252 | err = -EIO; | 253 | err = -EIO; |
253 | if (!err && outarg.nodeid) { | 254 | if (!err && outarg.nodeid) { |
254 | inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, | 255 | inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, |
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index b98b20de7405..68ae87cbafab 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
@@ -552,3 +552,8 @@ int fuse_ctl_add_conn(struct fuse_conn *fc); | |||
552 | * Remove connection from control filesystem | 552 | * Remove connection from control filesystem |
553 | */ | 553 | */ |
554 | void fuse_ctl_remove_conn(struct fuse_conn *fc); | 554 | void fuse_ctl_remove_conn(struct fuse_conn *fc); |
555 | |||
556 | /** | ||
557 | * Is file type valid? | ||
558 | */ | ||
559 | int fuse_valid_type(int m); | ||
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 5ab8e50e7808..608db81219a0 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -330,6 +330,8 @@ static int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev) | |||
330 | case OPT_ROOTMODE: | 330 | case OPT_ROOTMODE: |
331 | if (match_octal(&args[0], &value)) | 331 | if (match_octal(&args[0], &value)) |
332 | return 0; | 332 | return 0; |
333 | if (!fuse_valid_type(value)) | ||
334 | return 0; | ||
333 | d->rootmode = value; | 335 | d->rootmode = value; |
334 | d->rootmode_present = 1; | 336 | d->rootmode_present = 1; |
335 | break; | 337 | break; |
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c index 6618c1190252..12accb08fe02 100644 --- a/fs/gfs2/glock.c +++ b/fs/gfs2/glock.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/list.h> | 20 | #include <linux/list.h> |
21 | #include <linux/lm_interface.h> | 21 | #include <linux/lm_interface.h> |
22 | #include <linux/wait.h> | 22 | #include <linux/wait.h> |
23 | #include <linux/module.h> | ||
23 | #include <linux/rwsem.h> | 24 | #include <linux/rwsem.h> |
24 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
25 | 26 | ||
@@ -953,9 +954,6 @@ static void drop_bh(struct gfs2_glock *gl, unsigned int ret) | |||
953 | spin_unlock(&gl->gl_spin); | 954 | spin_unlock(&gl->gl_spin); |
954 | } | 955 | } |
955 | 956 | ||
956 | if (glops->go_drop_bh) | ||
957 | glops->go_drop_bh(gl); | ||
958 | |||
959 | spin_lock(&gl->gl_spin); | 957 | spin_lock(&gl->gl_spin); |
960 | gl->gl_req_gh = NULL; | 958 | gl->gl_req_gh = NULL; |
961 | gl->gl_req_bh = NULL; | 959 | gl->gl_req_bh = NULL; |
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index 46af55355513..39c8ae23bd9c 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c | |||
@@ -245,7 +245,6 @@ static void inode_go_inval(struct gfs2_glock *gl, int flags) | |||
245 | 245 | ||
246 | if (ip && S_ISREG(ip->i_inode.i_mode)) { | 246 | if (ip && S_ISREG(ip->i_inode.i_mode)) { |
247 | truncate_inode_pages(ip->i_inode.i_mapping, 0); | 247 | truncate_inode_pages(ip->i_inode.i_mapping, 0); |
248 | gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), !ip->i_inode.i_mapping->nrpages); | ||
249 | clear_bit(GIF_PAGED, &ip->i_flags); | 248 | clear_bit(GIF_PAGED, &ip->i_flags); |
250 | } | 249 | } |
251 | } | 250 | } |
@@ -459,6 +458,8 @@ const struct gfs2_glock_operations gfs2_inode_glops = { | |||
459 | }; | 458 | }; |
460 | 459 | ||
461 | const struct gfs2_glock_operations gfs2_rgrp_glops = { | 460 | const struct gfs2_glock_operations gfs2_rgrp_glops = { |
461 | .go_xmote_th = meta_go_sync, | ||
462 | .go_drop_th = meta_go_sync, | ||
462 | .go_inval = meta_go_inval, | 463 | .go_inval = meta_go_inval, |
463 | .go_demote_ok = rgrp_go_demote_ok, | 464 | .go_demote_ok = rgrp_go_demote_ok, |
464 | .go_lock = rgrp_go_lock, | 465 | .go_lock = rgrp_go_lock, |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index 12c80fd28db5..49f0dbf40d86 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -104,7 +104,6 @@ struct gfs2_glock_operations { | |||
104 | void (*go_xmote_th) (struct gfs2_glock *gl); | 104 | void (*go_xmote_th) (struct gfs2_glock *gl); |
105 | void (*go_xmote_bh) (struct gfs2_glock *gl); | 105 | void (*go_xmote_bh) (struct gfs2_glock *gl); |
106 | void (*go_drop_th) (struct gfs2_glock *gl); | 106 | void (*go_drop_th) (struct gfs2_glock *gl); |
107 | void (*go_drop_bh) (struct gfs2_glock *gl); | ||
108 | void (*go_inval) (struct gfs2_glock *gl, int flags); | 107 | void (*go_inval) (struct gfs2_glock *gl, int flags); |
109 | int (*go_demote_ok) (struct gfs2_glock *gl); | 108 | int (*go_demote_ok) (struct gfs2_glock *gl); |
110 | int (*go_lock) (struct gfs2_holder *gh); | 109 | int (*go_lock) (struct gfs2_holder *gh); |
@@ -416,7 +415,6 @@ struct gfs2_tune { | |||
416 | unsigned int gt_stall_secs; /* Detects trouble! */ | 415 | unsigned int gt_stall_secs; /* Detects trouble! */ |
417 | unsigned int gt_complain_secs; | 416 | unsigned int gt_complain_secs; |
418 | unsigned int gt_reclaim_limit; /* Max num of glocks in reclaim list */ | 417 | unsigned int gt_reclaim_limit; /* Max num of glocks in reclaim list */ |
419 | unsigned int gt_entries_per_readdir; | ||
420 | unsigned int gt_statfs_quantum; | 418 | unsigned int gt_statfs_quantum; |
421 | unsigned int gt_statfs_slow; | 419 | unsigned int gt_statfs_slow; |
422 | }; | 420 | }; |
diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index 0d6831a40565..df0b8b3018b9 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c | |||
@@ -43,7 +43,8 @@ static int iget_test(struct inode *inode, void *opaque) | |||
43 | struct gfs2_inode *ip = GFS2_I(inode); | 43 | struct gfs2_inode *ip = GFS2_I(inode); |
44 | struct gfs2_inum_host *inum = opaque; | 44 | struct gfs2_inum_host *inum = opaque; |
45 | 45 | ||
46 | if (ip->i_num.no_addr == inum->no_addr) | 46 | if (ip->i_num.no_addr == inum->no_addr && |
47 | inode->i_private != NULL) | ||
47 | return 1; | 48 | return 1; |
48 | 49 | ||
49 | return 0; | 50 | return 0; |
@@ -61,13 +62,13 @@ static int iget_set(struct inode *inode, void *opaque) | |||
61 | 62 | ||
62 | struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum_host *inum) | 63 | struct inode *gfs2_ilookup(struct super_block *sb, struct gfs2_inum_host *inum) |
63 | { | 64 | { |
64 | return ilookup5(sb, (unsigned long)inum->no_formal_ino, | 65 | return ilookup5(sb, (unsigned long)inum->no_addr, |
65 | iget_test, inum); | 66 | iget_test, inum); |
66 | } | 67 | } |
67 | 68 | ||
68 | static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum_host *inum) | 69 | static struct inode *gfs2_iget(struct super_block *sb, struct gfs2_inum_host *inum) |
69 | { | 70 | { |
70 | return iget5_locked(sb, (unsigned long)inum->no_formal_ino, | 71 | return iget5_locked(sb, (unsigned long)inum->no_addr, |
71 | iget_test, iget_set, inum); | 72 | iget_test, iget_set, inum); |
72 | } | 73 | } |
73 | 74 | ||
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index 56e33590b656..b3b7e8475359 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c | |||
@@ -266,9 +266,11 @@ skip_lock: | |||
266 | out: | 266 | out: |
267 | return error; | 267 | return error; |
268 | out_unlock: | 268 | out_unlock: |
269 | if (error == GLR_TRYFAILED) | ||
270 | error = AOP_TRUNCATED_PAGE; | ||
271 | unlock_page(page); | 269 | unlock_page(page); |
270 | if (error == GLR_TRYFAILED) { | ||
271 | error = AOP_TRUNCATED_PAGE; | ||
272 | yield(); | ||
273 | } | ||
272 | if (do_unlock) | 274 | if (do_unlock) |
273 | gfs2_holder_uninit(&gh); | 275 | gfs2_holder_uninit(&gh); |
274 | goto out; | 276 | goto out; |
@@ -364,6 +366,7 @@ static int gfs2_prepare_write(struct file *file, struct page *page, | |||
364 | if (error == GLR_TRYFAILED) { | 366 | if (error == GLR_TRYFAILED) { |
365 | unlock_page(page); | 367 | unlock_page(page); |
366 | error = AOP_TRUNCATED_PAGE; | 368 | error = AOP_TRUNCATED_PAGE; |
369 | yield(); | ||
367 | } | 370 | } |
368 | goto out_uninit; | 371 | goto out_uninit; |
369 | } | 372 | } |
diff --git a/fs/gfs2/ops_export.c b/fs/gfs2/ops_export.c index 1de05b63d43a..aad918337a46 100644 --- a/fs/gfs2/ops_export.c +++ b/fs/gfs2/ops_export.c | |||
@@ -38,14 +38,11 @@ static struct dentry *gfs2_decode_fh(struct super_block *sb, | |||
38 | struct gfs2_fh_obj fh_obj; | 38 | struct gfs2_fh_obj fh_obj; |
39 | struct gfs2_inum_host *this, parent; | 39 | struct gfs2_inum_host *this, parent; |
40 | 40 | ||
41 | if (fh_type != fh_len) | ||
42 | return NULL; | ||
43 | |||
44 | this = &fh_obj.this; | 41 | this = &fh_obj.this; |
45 | fh_obj.imode = DT_UNKNOWN; | 42 | fh_obj.imode = DT_UNKNOWN; |
46 | memset(&parent, 0, sizeof(struct gfs2_inum)); | 43 | memset(&parent, 0, sizeof(struct gfs2_inum)); |
47 | 44 | ||
48 | switch (fh_type) { | 45 | switch (fh_len) { |
49 | case GFS2_LARGE_FH_SIZE: | 46 | case GFS2_LARGE_FH_SIZE: |
50 | parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32; | 47 | parent.no_formal_ino = ((u64)be32_to_cpu(fh[4])) << 32; |
51 | parent.no_formal_ino |= be32_to_cpu(fh[5]); | 48 | parent.no_formal_ino |= be32_to_cpu(fh[5]); |
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index ee80b8a5e7bc..ee54cb667083 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
@@ -840,7 +840,7 @@ static struct super_block* get_gfs2_sb(const char *dev_name) | |||
840 | } | 840 | } |
841 | 841 | ||
842 | printk(KERN_WARNING "GFS2: Unrecognized block device or " | 842 | printk(KERN_WARNING "GFS2: Unrecognized block device or " |
843 | "mount point %s", dev_name); | 843 | "mount point %s\n", dev_name); |
844 | 844 | ||
845 | free_nd: | 845 | free_nd: |
846 | path_release(&nd); | 846 | path_release(&nd); |
diff --git a/fs/gfs2/quota.c b/fs/gfs2/quota.c index d0db881b55d2..c186857e48a8 100644 --- a/fs/gfs2/quota.c +++ b/fs/gfs2/quota.c | |||
@@ -279,7 +279,7 @@ static int bh_get(struct gfs2_quota_data *qd) | |||
279 | (bh->b_data + sizeof(struct gfs2_meta_header) + | 279 | (bh->b_data + sizeof(struct gfs2_meta_header) + |
280 | offset * sizeof(struct gfs2_quota_change)); | 280 | offset * sizeof(struct gfs2_quota_change)); |
281 | 281 | ||
282 | mutex_lock(&sdp->sd_quota_mutex); | 282 | mutex_unlock(&sdp->sd_quota_mutex); |
283 | 283 | ||
284 | return 0; | 284 | return 0; |
285 | 285 | ||
diff --git a/fs/gfs2/super.c b/fs/gfs2/super.c index 70f424fcf1cd..4fdda974dc83 100644 --- a/fs/gfs2/super.c +++ b/fs/gfs2/super.c | |||
@@ -76,7 +76,6 @@ void gfs2_tune_init(struct gfs2_tune *gt) | |||
76 | gt->gt_stall_secs = 600; | 76 | gt->gt_stall_secs = 600; |
77 | gt->gt_complain_secs = 10; | 77 | gt->gt_complain_secs = 10; |
78 | gt->gt_reclaim_limit = 5000; | 78 | gt->gt_reclaim_limit = 5000; |
79 | gt->gt_entries_per_readdir = 32; | ||
80 | gt->gt_statfs_quantum = 30; | 79 | gt->gt_statfs_quantum = 30; |
81 | gt->gt_statfs_slow = 0; | 80 | gt->gt_statfs_slow = 0; |
82 | } | 81 | } |
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c index e965eb11d76f..fd301a910122 100644 --- a/fs/hostfs/hostfs_kern.c +++ b/fs/hostfs/hostfs_kern.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include "hostfs.h" | 20 | #include "hostfs.h" |
21 | #include "kern_util.h" | 21 | #include "kern_util.h" |
22 | #include "kern.h" | 22 | #include "kern.h" |
23 | #include "user_util.h" | ||
24 | #include "init.h" | 23 | #include "init.h" |
25 | 24 | ||
26 | struct hostfs_inode_info { | 25 | struct hostfs_inode_info { |
@@ -47,7 +46,7 @@ struct dentry_operations hostfs_dentry_ops = { | |||
47 | }; | 46 | }; |
48 | 47 | ||
49 | /* Changed in hostfs_args before the kernel starts running */ | 48 | /* Changed in hostfs_args before the kernel starts running */ |
50 | static char *root_ino = "/"; | 49 | static char *root_ino = ""; |
51 | static int append = 0; | 50 | static int append = 0; |
52 | 51 | ||
53 | #define HOSTFS_SUPER_MAGIC 0x00c0ffee | 52 | #define HOSTFS_SUPER_MAGIC 0x00c0ffee |
@@ -939,7 +938,7 @@ static const struct address_space_operations hostfs_link_aops = { | |||
939 | static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) | 938 | static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) |
940 | { | 939 | { |
941 | struct inode *root_inode; | 940 | struct inode *root_inode; |
942 | char *name, *data = d; | 941 | char *host_root_path, *req_root = d; |
943 | int err; | 942 | int err; |
944 | 943 | ||
945 | sb->s_blocksize = 1024; | 944 | sb->s_blocksize = 1024; |
@@ -947,15 +946,17 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) | |||
947 | sb->s_magic = HOSTFS_SUPER_MAGIC; | 946 | sb->s_magic = HOSTFS_SUPER_MAGIC; |
948 | sb->s_op = &hostfs_sbops; | 947 | sb->s_op = &hostfs_sbops; |
949 | 948 | ||
950 | if((data == NULL) || (*data == '\0')) | 949 | /* NULL is printed as <NULL> by sprintf: avoid that. */ |
951 | data = root_ino; | 950 | if (req_root == NULL) |
951 | req_root = ""; | ||
952 | 952 | ||
953 | err = -ENOMEM; | 953 | err = -ENOMEM; |
954 | name = kmalloc(strlen(data) + 1, GFP_KERNEL); | 954 | host_root_path = kmalloc(strlen(root_ino) + 1 |
955 | if(name == NULL) | 955 | + strlen(req_root) + 1, GFP_KERNEL); |
956 | if(host_root_path == NULL) | ||
956 | goto out; | 957 | goto out; |
957 | 958 | ||
958 | strcpy(name, data); | 959 | sprintf(host_root_path, "%s/%s", root_ino, req_root); |
959 | 960 | ||
960 | root_inode = iget(sb, 0); | 961 | root_inode = iget(sb, 0); |
961 | if(root_inode == NULL) | 962 | if(root_inode == NULL) |
@@ -965,7 +966,10 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) | |||
965 | if(err) | 966 | if(err) |
966 | goto out_put; | 967 | goto out_put; |
967 | 968 | ||
968 | HOSTFS_I(root_inode)->host_filename = name; | 969 | HOSTFS_I(root_inode)->host_filename = host_root_path; |
970 | /* Avoid that in the error path, iput(root_inode) frees again | ||
971 | * host_root_path through hostfs_destroy_inode! */ | ||
972 | host_root_path = NULL; | ||
969 | 973 | ||
970 | err = -ENOMEM; | 974 | err = -ENOMEM; |
971 | sb->s_root = d_alloc_root(root_inode); | 975 | sb->s_root = d_alloc_root(root_inode); |
@@ -977,7 +981,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 */ | 981 | /* No iput in this case because the dput does that for us */ |
978 | dput(sb->s_root); | 982 | dput(sb->s_root); |
979 | sb->s_root = NULL; | 983 | sb->s_root = NULL; |
980 | goto out_free; | 984 | goto out; |
981 | } | 985 | } |
982 | 986 | ||
983 | return(0); | 987 | return(0); |
@@ -985,7 +989,7 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent) | |||
985 | out_put: | 989 | out_put: |
986 | iput(root_inode); | 990 | iput(root_inode); |
987 | out_free: | 991 | out_free: |
988 | kfree(name); | 992 | kfree(host_root_path); |
989 | out: | 993 | out: |
990 | return(err); | 994 | return(err); |
991 | } | 995 | } |
diff --git a/fs/jffs2/background.c b/fs/jffs2/background.c index 6eb3daebd563..888f236e5494 100644 --- a/fs/jffs2/background.c +++ b/fs/jffs2/background.c | |||
@@ -99,7 +99,13 @@ static int jffs2_garbage_collect_thread(void *_c) | |||
99 | if (try_to_freeze()) | 99 | if (try_to_freeze()) |
100 | continue; | 100 | continue; |
101 | 101 | ||
102 | cond_resched(); | 102 | /* This thread is purely an optimisation. But if it runs when |
103 | other things could be running, it actually makes things a | ||
104 | lot worse. Use yield() and put it at the back of the runqueue | ||
105 | every time. Especially during boot, pulling an inode in | ||
106 | with read_inode() is much preferable to having the GC thread | ||
107 | get there first. */ | ||
108 | yield(); | ||
103 | 109 | ||
104 | /* Put_super will send a SIGKILL and then wait on the sem. | 110 | /* Put_super will send a SIGKILL and then wait on the sem. |
105 | */ | 111 | */ |
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c index 58a0b912e9d0..717a48cf7df2 100644 --- a/fs/jffs2/readinode.c +++ b/fs/jffs2/readinode.c | |||
@@ -373,7 +373,14 @@ free_out: | |||
373 | static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, struct jffs2_unknown_node *un) | 373 | static inline int read_unknown(struct jffs2_sb_info *c, struct jffs2_raw_node_ref *ref, struct jffs2_unknown_node *un) |
374 | { | 374 | { |
375 | /* We don't mark unknown nodes as REF_UNCHECKED */ | 375 | /* We don't mark unknown nodes as REF_UNCHECKED */ |
376 | BUG_ON(ref_flags(ref) == REF_UNCHECKED); | 376 | if (ref_flags(ref) == REF_UNCHECKED) { |
377 | JFFS2_ERROR("REF_UNCHECKED but unknown node at %#08x\n", | ||
378 | ref_offset(ref)); | ||
379 | JFFS2_ERROR("Node is {%04x,%04x,%08x,%08x}. Please report this error.\n", | ||
380 | je16_to_cpu(un->magic), je16_to_cpu(un->nodetype), | ||
381 | je32_to_cpu(un->totlen), je32_to_cpu(un->hdr_crc)); | ||
382 | return 1; | ||
383 | } | ||
377 | 384 | ||
378 | un->nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(un->nodetype)); | 385 | un->nodetype = cpu_to_je16(JFFS2_NODE_ACCURATE | je16_to_cpu(un->nodetype)); |
379 | 386 | ||
@@ -576,6 +583,13 @@ static int jffs2_get_inode_nodes(struct jffs2_sb_info *c, struct jffs2_inode_inf | |||
576 | jffs2_mark_node_obsolete(c, ref); | 583 | jffs2_mark_node_obsolete(c, ref); |
577 | goto cont; | 584 | goto cont; |
578 | } | 585 | } |
586 | /* Due to poor choice of crc32 seed, an all-zero node will have a correct CRC */ | ||
587 | if (!je32_to_cpu(node->u.hdr_crc) && !je16_to_cpu(node->u.nodetype) && | ||
588 | !je16_to_cpu(node->u.magic) && !je32_to_cpu(node->u.totlen)) { | ||
589 | JFFS2_NOTICE("All zero node header at %#08x.\n", ref_offset(ref)); | ||
590 | jffs2_mark_node_obsolete(c, ref); | ||
591 | goto cont; | ||
592 | } | ||
579 | 593 | ||
580 | switch (je16_to_cpu(node->u.nodetype)) { | 594 | switch (je16_to_cpu(node->u.nodetype)) { |
581 | 595 | ||
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index 31c1475d922a..7fb45bd4915c 100644 --- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c | |||
@@ -734,6 +734,15 @@ scan_more: | |||
734 | ofs += 4; | 734 | ofs += 4; |
735 | continue; | 735 | continue; |
736 | } | 736 | } |
737 | /* Due to poor choice of crc32 seed, an all-zero node will have a correct CRC */ | ||
738 | if (!je32_to_cpu(node->hdr_crc) && !je16_to_cpu(node->nodetype) && | ||
739 | !je16_to_cpu(node->magic) && !je32_to_cpu(node->totlen)) { | ||
740 | noisy_printk(&noise, "jffs2_scan_eraseblock(): All zero node header at 0x%08x.\n", ofs); | ||
741 | if ((err = jffs2_scan_dirty_space(c, jeb, 4))) | ||
742 | return err; | ||
743 | ofs += 4; | ||
744 | continue; | ||
745 | } | ||
737 | 746 | ||
738 | if (ofs + je32_to_cpu(node->totlen) > | 747 | if (ofs + je32_to_cpu(node->totlen) > |
739 | jeb->offset + c->sector_size) { | 748 | jeb->offset + c->sector_size) { |
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c index de718e3a1692..4fac6dd53954 100644 --- a/fs/jffs2/wbuf.c +++ b/fs/jffs2/wbuf.c | |||
@@ -238,7 +238,10 @@ static void jffs2_wbuf_recover(struct jffs2_sb_info *c) | |||
238 | jeb = &c->blocks[c->wbuf_ofs / c->sector_size]; | 238 | jeb = &c->blocks[c->wbuf_ofs / c->sector_size]; |
239 | 239 | ||
240 | spin_lock(&c->erase_completion_lock); | 240 | spin_lock(&c->erase_completion_lock); |
241 | jffs2_block_refile(c, jeb, REFILE_NOTEMPTY); | 241 | if (c->wbuf_ofs % c->mtd->erasesize) |
242 | jffs2_block_refile(c, jeb, REFILE_NOTEMPTY); | ||
243 | else | ||
244 | jffs2_block_refile(c, jeb, REFILE_ANYWAY); | ||
242 | spin_unlock(&c->erase_completion_lock); | 245 | spin_unlock(&c->erase_completion_lock); |
243 | 246 | ||
244 | BUG_ON(!ref_obsolete(jeb->last_node)); | 247 | BUG_ON(!ref_obsolete(jeb->last_node)); |
@@ -1087,7 +1090,7 @@ int jffs2_write_nand_badblock(struct jffs2_sb_info *c, struct jffs2_eraseblock * | |||
1087 | if (!c->mtd->block_markbad) | 1090 | if (!c->mtd->block_markbad) |
1088 | return 1; // What else can we do? | 1091 | return 1; // What else can we do? |
1089 | 1092 | ||
1090 | D1(printk(KERN_WARNING "jffs2_write_nand_badblock(): Marking bad block at %08x\n", bad_offset)); | 1093 | printk(KERN_WARNING "JFFS2: marking eraseblock at %08x\n as bad", bad_offset); |
1091 | ret = c->mtd->block_markbad(c->mtd, bad_offset); | 1094 | ret = c->mtd->block_markbad(c->mtd, bad_offset); |
1092 | 1095 | ||
1093 | if (ret) { | 1096 | if (ret) { |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index af53c02f473b..93d046c85f52 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -429,7 +429,8 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | |||
429 | int err; | 429 | int err; |
430 | 430 | ||
431 | /* Flush out writes to the server in order to update c/mtime */ | 431 | /* Flush out writes to the server in order to update c/mtime */ |
432 | nfs_sync_mapping_range(inode->i_mapping, 0, 0, FLUSH_NOCOMMIT); | 432 | if (S_ISREG(inode->i_mode)) |
433 | nfs_sync_mapping_range(inode->i_mapping, 0, 0, FLUSH_NOCOMMIT); | ||
433 | 434 | ||
434 | /* | 435 | /* |
435 | * We may force a getattr if the user cares about atime. | 436 | * We may force a getattr if the user cares about atime. |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index bb516a2cfbaf..f1eae44b9a1a 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -151,10 +151,10 @@ int __init register_nfs_fs(void) | |||
151 | if (ret < 0) | 151 | if (ret < 0) |
152 | goto error_0; | 152 | goto error_0; |
153 | 153 | ||
154 | #ifdef CONFIG_NFS_V4 | ||
155 | ret = nfs_register_sysctl(); | 154 | ret = nfs_register_sysctl(); |
156 | if (ret < 0) | 155 | if (ret < 0) |
157 | goto error_1; | 156 | goto error_1; |
157 | #ifdef CONFIG_NFS_V4 | ||
158 | ret = register_filesystem(&nfs4_fs_type); | 158 | ret = register_filesystem(&nfs4_fs_type); |
159 | if (ret < 0) | 159 | if (ret < 0) |
160 | goto error_2; | 160 | goto error_2; |
@@ -165,9 +165,9 @@ int __init register_nfs_fs(void) | |||
165 | #ifdef CONFIG_NFS_V4 | 165 | #ifdef CONFIG_NFS_V4 |
166 | error_2: | 166 | error_2: |
167 | nfs_unregister_sysctl(); | 167 | nfs_unregister_sysctl(); |
168 | #endif | ||
168 | error_1: | 169 | error_1: |
169 | unregister_filesystem(&nfs_fs_type); | 170 | unregister_filesystem(&nfs_fs_type); |
170 | #endif | ||
171 | error_0: | 171 | error_0: |
172 | return ret; | 172 | return ret; |
173 | } | 173 | } |
diff --git a/fs/nfs/sysctl.c b/fs/nfs/sysctl.c index fcdcafbb3293..b62481dabae9 100644 --- a/fs/nfs/sysctl.c +++ b/fs/nfs/sysctl.c | |||
@@ -50,6 +50,14 @@ static ctl_table nfs_cb_sysctls[] = { | |||
50 | .proc_handler = &proc_dointvec_jiffies, | 50 | .proc_handler = &proc_dointvec_jiffies, |
51 | .strategy = &sysctl_jiffies, | 51 | .strategy = &sysctl_jiffies, |
52 | }, | 52 | }, |
53 | { | ||
54 | .ctl_name = CTL_UNNUMBERED, | ||
55 | .procname = "nfs_congestion_kb", | ||
56 | .data = &nfs_congestion_kb, | ||
57 | .maxlen = sizeof(nfs_congestion_kb), | ||
58 | .mode = 0644, | ||
59 | .proc_handler = &proc_dointvec, | ||
60 | }, | ||
53 | { .ctl_name = 0 } | 61 | { .ctl_name = 0 } |
54 | }; | 62 | }; |
55 | 63 | ||
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index febdade91670..2867e6b7096f 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/pagemap.h> | 12 | #include <linux/pagemap.h> |
13 | #include <linux/file.h> | 13 | #include <linux/file.h> |
14 | #include <linux/writeback.h> | 14 | #include <linux/writeback.h> |
15 | #include <linux/swap.h> | ||
15 | 16 | ||
16 | #include <linux/sunrpc/clnt.h> | 17 | #include <linux/sunrpc/clnt.h> |
17 | #include <linux/nfs_fs.h> | 18 | #include <linux/nfs_fs.h> |
@@ -38,7 +39,6 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context*, | |||
38 | struct page *, | 39 | struct page *, |
39 | unsigned int, unsigned int); | 40 | unsigned int, unsigned int); |
40 | static void nfs_mark_request_dirty(struct nfs_page *req); | 41 | static void nfs_mark_request_dirty(struct nfs_page *req); |
41 | static int nfs_wait_on_write_congestion(struct address_space *, int); | ||
42 | static long nfs_flush_mapping(struct address_space *mapping, struct writeback_control *wbc, int how); | 42 | static long nfs_flush_mapping(struct address_space *mapping, struct writeback_control *wbc, int how); |
43 | static const struct rpc_call_ops nfs_write_partial_ops; | 43 | static const struct rpc_call_ops nfs_write_partial_ops; |
44 | static const struct rpc_call_ops nfs_write_full_ops; | 44 | static const struct rpc_call_ops nfs_write_full_ops; |
@@ -48,8 +48,6 @@ static struct kmem_cache *nfs_wdata_cachep; | |||
48 | static mempool_t *nfs_wdata_mempool; | 48 | static mempool_t *nfs_wdata_mempool; |
49 | static mempool_t *nfs_commit_mempool; | 49 | static mempool_t *nfs_commit_mempool; |
50 | 50 | ||
51 | static DECLARE_WAIT_QUEUE_HEAD(nfs_write_congestion); | ||
52 | |||
53 | struct nfs_write_data *nfs_commit_alloc(void) | 51 | struct nfs_write_data *nfs_commit_alloc(void) |
54 | { | 52 | { |
55 | struct nfs_write_data *p = mempool_alloc(nfs_commit_mempool, GFP_NOFS); | 53 | struct nfs_write_data *p = mempool_alloc(nfs_commit_mempool, GFP_NOFS); |
@@ -211,6 +209,40 @@ static int wb_priority(struct writeback_control *wbc) | |||
211 | } | 209 | } |
212 | 210 | ||
213 | /* | 211 | /* |
212 | * NFS congestion control | ||
213 | */ | ||
214 | |||
215 | int nfs_congestion_kb; | ||
216 | |||
217 | #define NFS_CONGESTION_ON_THRESH (nfs_congestion_kb >> (PAGE_SHIFT-10)) | ||
218 | #define NFS_CONGESTION_OFF_THRESH \ | ||
219 | (NFS_CONGESTION_ON_THRESH - (NFS_CONGESTION_ON_THRESH >> 2)) | ||
220 | |||
221 | static void nfs_set_page_writeback(struct page *page) | ||
222 | { | ||
223 | if (!test_set_page_writeback(page)) { | ||
224 | struct inode *inode = page->mapping->host; | ||
225 | struct nfs_server *nfss = NFS_SERVER(inode); | ||
226 | |||
227 | if (atomic_inc_return(&nfss->writeback) > | ||
228 | NFS_CONGESTION_ON_THRESH) | ||
229 | set_bdi_congested(&nfss->backing_dev_info, WRITE); | ||
230 | } | ||
231 | } | ||
232 | |||
233 | static void nfs_end_page_writeback(struct page *page) | ||
234 | { | ||
235 | struct inode *inode = page->mapping->host; | ||
236 | struct nfs_server *nfss = NFS_SERVER(inode); | ||
237 | |||
238 | end_page_writeback(page); | ||
239 | if (atomic_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH) { | ||
240 | clear_bdi_congested(&nfss->backing_dev_info, WRITE); | ||
241 | congestion_end(WRITE); | ||
242 | } | ||
243 | } | ||
244 | |||
245 | /* | ||
214 | * Find an associated nfs write request, and prepare to flush it out | 246 | * Find an associated nfs write request, and prepare to flush it out |
215 | * Returns 1 if there was no write request, or if the request was | 247 | * Returns 1 if there was no write request, or if the request was |
216 | * already tagged by nfs_set_page_dirty.Returns 0 if the request | 248 | * already tagged by nfs_set_page_dirty.Returns 0 if the request |
@@ -247,7 +279,7 @@ static int nfs_page_mark_flush(struct page *page) | |||
247 | spin_unlock(req_lock); | 279 | spin_unlock(req_lock); |
248 | if (test_and_set_bit(PG_FLUSHING, &req->wb_flags) == 0) { | 280 | if (test_and_set_bit(PG_FLUSHING, &req->wb_flags) == 0) { |
249 | nfs_mark_request_dirty(req); | 281 | nfs_mark_request_dirty(req); |
250 | set_page_writeback(page); | 282 | nfs_set_page_writeback(page); |
251 | } | 283 | } |
252 | ret = test_bit(PG_NEED_FLUSH, &req->wb_flags); | 284 | ret = test_bit(PG_NEED_FLUSH, &req->wb_flags); |
253 | nfs_unlock_request(req); | 285 | nfs_unlock_request(req); |
@@ -302,13 +334,8 @@ int nfs_writepage(struct page *page, struct writeback_control *wbc) | |||
302 | return err; | 334 | return err; |
303 | } | 335 | } |
304 | 336 | ||
305 | /* | ||
306 | * Note: causes nfs_update_request() to block on the assumption | ||
307 | * that the writeback is generated due to memory pressure. | ||
308 | */ | ||
309 | int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc) | 337 | int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc) |
310 | { | 338 | { |
311 | struct backing_dev_info *bdi = mapping->backing_dev_info; | ||
312 | struct inode *inode = mapping->host; | 339 | struct inode *inode = mapping->host; |
313 | int err; | 340 | int err; |
314 | 341 | ||
@@ -317,20 +344,12 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc) | |||
317 | err = generic_writepages(mapping, wbc); | 344 | err = generic_writepages(mapping, wbc); |
318 | if (err) | 345 | if (err) |
319 | return err; | 346 | return err; |
320 | while (test_and_set_bit(BDI_write_congested, &bdi->state) != 0) { | ||
321 | if (wbc->nonblocking) | ||
322 | return 0; | ||
323 | nfs_wait_on_write_congestion(mapping, 0); | ||
324 | } | ||
325 | err = nfs_flush_mapping(mapping, wbc, wb_priority(wbc)); | 347 | err = nfs_flush_mapping(mapping, wbc, wb_priority(wbc)); |
326 | if (err < 0) | 348 | if (err < 0) |
327 | goto out; | 349 | goto out; |
328 | nfs_add_stats(inode, NFSIOS_WRITEPAGES, err); | 350 | nfs_add_stats(inode, NFSIOS_WRITEPAGES, err); |
329 | err = 0; | 351 | err = 0; |
330 | out: | 352 | out: |
331 | clear_bit(BDI_write_congested, &bdi->state); | ||
332 | wake_up_all(&nfs_write_congestion); | ||
333 | congestion_end(WRITE); | ||
334 | return err; | 353 | return err; |
335 | } | 354 | } |
336 | 355 | ||
@@ -360,7 +379,7 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req) | |||
360 | } | 379 | } |
361 | 380 | ||
362 | /* | 381 | /* |
363 | * Insert a write request into an inode | 382 | * Remove a write request from an inode |
364 | */ | 383 | */ |
365 | static void nfs_inode_remove_request(struct nfs_page *req) | 384 | static void nfs_inode_remove_request(struct nfs_page *req) |
366 | { | 385 | { |
@@ -531,10 +550,10 @@ static inline int nfs_scan_commit(struct inode *inode, struct list_head *dst, un | |||
531 | } | 550 | } |
532 | #endif | 551 | #endif |
533 | 552 | ||
534 | static int nfs_wait_on_write_congestion(struct address_space *mapping, int intr) | 553 | static int nfs_wait_on_write_congestion(struct address_space *mapping) |
535 | { | 554 | { |
555 | struct inode *inode = mapping->host; | ||
536 | struct backing_dev_info *bdi = mapping->backing_dev_info; | 556 | struct backing_dev_info *bdi = mapping->backing_dev_info; |
537 | DEFINE_WAIT(wait); | ||
538 | int ret = 0; | 557 | int ret = 0; |
539 | 558 | ||
540 | might_sleep(); | 559 | might_sleep(); |
@@ -542,31 +561,23 @@ static int nfs_wait_on_write_congestion(struct address_space *mapping, int intr) | |||
542 | if (!bdi_write_congested(bdi)) | 561 | if (!bdi_write_congested(bdi)) |
543 | return 0; | 562 | return 0; |
544 | 563 | ||
545 | nfs_inc_stats(mapping->host, NFSIOS_CONGESTIONWAIT); | 564 | nfs_inc_stats(inode, NFSIOS_CONGESTIONWAIT); |
546 | 565 | ||
547 | if (intr) { | 566 | do { |
548 | struct rpc_clnt *clnt = NFS_CLIENT(mapping->host); | 567 | struct rpc_clnt *clnt = NFS_CLIENT(inode); |
549 | sigset_t oldset; | 568 | sigset_t oldset; |
550 | 569 | ||
551 | rpc_clnt_sigmask(clnt, &oldset); | 570 | rpc_clnt_sigmask(clnt, &oldset); |
552 | prepare_to_wait(&nfs_write_congestion, &wait, TASK_INTERRUPTIBLE); | 571 | ret = congestion_wait_interruptible(WRITE, HZ/10); |
553 | if (bdi_write_congested(bdi)) { | ||
554 | if (signalled()) | ||
555 | ret = -ERESTARTSYS; | ||
556 | else | ||
557 | schedule(); | ||
558 | } | ||
559 | rpc_clnt_sigunmask(clnt, &oldset); | 572 | rpc_clnt_sigunmask(clnt, &oldset); |
560 | } else { | 573 | if (ret == -ERESTARTSYS) |
561 | prepare_to_wait(&nfs_write_congestion, &wait, TASK_UNINTERRUPTIBLE); | 574 | break; |
562 | if (bdi_write_congested(bdi)) | 575 | ret = 0; |
563 | schedule(); | 576 | } while (bdi_write_congested(bdi)); |
564 | } | 577 | |
565 | finish_wait(&nfs_write_congestion, &wait); | ||
566 | return ret; | 578 | return ret; |
567 | } | 579 | } |
568 | 580 | ||
569 | |||
570 | /* | 581 | /* |
571 | * Try to update any existing write request, or create one if there is none. | 582 | * Try to update any existing write request, or create one if there is none. |
572 | * In order to match, the request's credentials must match those of | 583 | * In order to match, the request's credentials must match those of |
@@ -577,14 +588,15 @@ static int nfs_wait_on_write_congestion(struct address_space *mapping, int intr) | |||
577 | static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, | 588 | static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, |
578 | struct page *page, unsigned int offset, unsigned int bytes) | 589 | struct page *page, unsigned int offset, unsigned int bytes) |
579 | { | 590 | { |
580 | struct inode *inode = page->mapping->host; | 591 | struct address_space *mapping = page->mapping; |
592 | struct inode *inode = mapping->host; | ||
581 | struct nfs_inode *nfsi = NFS_I(inode); | 593 | struct nfs_inode *nfsi = NFS_I(inode); |
582 | struct nfs_page *req, *new = NULL; | 594 | struct nfs_page *req, *new = NULL; |
583 | unsigned long rqend, end; | 595 | unsigned long rqend, end; |
584 | 596 | ||
585 | end = offset + bytes; | 597 | end = offset + bytes; |
586 | 598 | ||
587 | if (nfs_wait_on_write_congestion(page->mapping, NFS_SERVER(inode)->flags & NFS_MOUNT_INTR)) | 599 | if (nfs_wait_on_write_congestion(mapping)) |
588 | return ERR_PTR(-ERESTARTSYS); | 600 | return ERR_PTR(-ERESTARTSYS); |
589 | for (;;) { | 601 | for (;;) { |
590 | /* Loop over all inode entries and see if we find | 602 | /* Loop over all inode entries and see if we find |
@@ -727,7 +739,7 @@ int nfs_updatepage(struct file *file, struct page *page, | |||
727 | 739 | ||
728 | static void nfs_writepage_release(struct nfs_page *req) | 740 | static void nfs_writepage_release(struct nfs_page *req) |
729 | { | 741 | { |
730 | end_page_writeback(req->wb_page); | 742 | nfs_end_page_writeback(req->wb_page); |
731 | 743 | ||
732 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | 744 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) |
733 | if (!PageError(req->wb_page)) { | 745 | if (!PageError(req->wb_page)) { |
@@ -1042,12 +1054,12 @@ static void nfs_writeback_done_full(struct rpc_task *task, void *calldata) | |||
1042 | if (task->tk_status < 0) { | 1054 | if (task->tk_status < 0) { |
1043 | nfs_set_pageerror(page); | 1055 | nfs_set_pageerror(page); |
1044 | req->wb_context->error = task->tk_status; | 1056 | req->wb_context->error = task->tk_status; |
1045 | end_page_writeback(page); | 1057 | nfs_end_page_writeback(page); |
1046 | nfs_inode_remove_request(req); | 1058 | nfs_inode_remove_request(req); |
1047 | dprintk(", error = %d\n", task->tk_status); | 1059 | dprintk(", error = %d\n", task->tk_status); |
1048 | goto next; | 1060 | goto next; |
1049 | } | 1061 | } |
1050 | end_page_writeback(page); | 1062 | nfs_end_page_writeback(page); |
1051 | 1063 | ||
1052 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | 1064 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) |
1053 | if (data->args.stable != NFS_UNSTABLE || data->verf.committed == NFS_FILE_SYNC) { | 1065 | if (data->args.stable != NFS_UNSTABLE || data->verf.committed == NFS_FILE_SYNC) { |
@@ -1514,6 +1526,26 @@ int __init nfs_init_writepagecache(void) | |||
1514 | if (nfs_commit_mempool == NULL) | 1526 | if (nfs_commit_mempool == NULL) |
1515 | return -ENOMEM; | 1527 | return -ENOMEM; |
1516 | 1528 | ||
1529 | /* | ||
1530 | * NFS congestion size, scale with available memory. | ||
1531 | * | ||
1532 | * 64MB: 8192k | ||
1533 | * 128MB: 11585k | ||
1534 | * 256MB: 16384k | ||
1535 | * 512MB: 23170k | ||
1536 | * 1GB: 32768k | ||
1537 | * 2GB: 46340k | ||
1538 | * 4GB: 65536k | ||
1539 | * 8GB: 92681k | ||
1540 | * 16GB: 131072k | ||
1541 | * | ||
1542 | * This allows larger machines to have larger/more transfers. | ||
1543 | * Limit the default to 256M | ||
1544 | */ | ||
1545 | nfs_congestion_kb = (16*int_sqrt(totalram_pages)) << (PAGE_SHIFT-10); | ||
1546 | if (nfs_congestion_kb > 256*1024) | ||
1547 | nfs_congestion_kb = 256*1024; | ||
1548 | |||
1517 | return 0; | 1549 | return 0; |
1518 | } | 1550 | } |
1519 | 1551 | ||
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 6f677988c71d..7e4bb0af24d7 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c | |||
@@ -859,8 +859,8 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp, | |||
859 | #define NFS3_ENTRY_BAGGAGE (2 + 1 + 2 + 1) | 859 | #define NFS3_ENTRY_BAGGAGE (2 + 1 + 2 + 1) |
860 | #define NFS3_ENTRYPLUS_BAGGAGE (1 + 21 + 1 + (NFS3_FHSIZE >> 2)) | 860 | #define NFS3_ENTRYPLUS_BAGGAGE (1 + 21 + 1 + (NFS3_FHSIZE >> 2)) |
861 | static int | 861 | static int |
862 | encode_entry(struct readdir_cd *ccd, const char *name, | 862 | encode_entry(struct readdir_cd *ccd, const char *name, int namlen, |
863 | int namlen, off_t offset, ino_t ino, unsigned int d_type, int plus) | 863 | loff_t offset, ino_t ino, unsigned int d_type, int plus) |
864 | { | 864 | { |
865 | struct nfsd3_readdirres *cd = container_of(ccd, struct nfsd3_readdirres, | 865 | struct nfsd3_readdirres *cd = container_of(ccd, struct nfsd3_readdirres, |
866 | common); | 866 | common); |
@@ -880,7 +880,7 @@ encode_entry(struct readdir_cd *ccd, const char *name, | |||
880 | *cd->offset1 = htonl(offset64 & 0xffffffff); | 880 | *cd->offset1 = htonl(offset64 & 0xffffffff); |
881 | cd->offset1 = NULL; | 881 | cd->offset1 = NULL; |
882 | } else { | 882 | } else { |
883 | xdr_encode_hyper(cd->offset, (u64) offset); | 883 | xdr_encode_hyper(cd->offset, offset64); |
884 | } | 884 | } |
885 | } | 885 | } |
886 | 886 | ||
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index 832673b14587..673a53c014a3 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c | |||
@@ -228,7 +228,7 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, | |||
228 | struct posix_acl_summary pas; | 228 | struct posix_acl_summary pas; |
229 | unsigned short deny; | 229 | unsigned short deny; |
230 | int eflag = ((flags & NFS4_ACL_TYPE_DEFAULT) ? | 230 | int eflag = ((flags & NFS4_ACL_TYPE_DEFAULT) ? |
231 | NFS4_INHERITANCE_FLAGS : 0); | 231 | NFS4_INHERITANCE_FLAGS | NFS4_ACE_INHERIT_ONLY_ACE : 0); |
232 | 232 | ||
233 | BUG_ON(pacl->a_count < 3); | 233 | BUG_ON(pacl->a_count < 3); |
234 | summarize_posix_acl(pacl, &pas); | 234 | summarize_posix_acl(pacl, &pas); |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 9e4067999209..af360705e551 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -750,9 +750,8 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
750 | status = nfserr_clid_inuse; | 750 | status = nfserr_clid_inuse; |
751 | if (!cmp_creds(&conf->cl_cred, &rqstp->rq_cred) | 751 | if (!cmp_creds(&conf->cl_cred, &rqstp->rq_cred) |
752 | || conf->cl_addr != sin->sin_addr.s_addr) { | 752 | || conf->cl_addr != sin->sin_addr.s_addr) { |
753 | printk("NFSD: setclientid: string in use by client" | 753 | dprintk("NFSD: setclientid: string in use by client" |
754 | "(clientid %08x/%08x)\n", | 754 | "at %u.%u.%u.%u\n", NIPQUAD(conf->cl_addr)); |
755 | conf->cl_clientid.cl_boot, conf->cl_clientid.cl_id); | ||
756 | goto out; | 755 | goto out; |
757 | } | 756 | } |
758 | } | 757 | } |
@@ -3261,7 +3260,6 @@ __nfs4_state_shutdown(void) | |||
3261 | unhash_delegation(dp); | 3260 | unhash_delegation(dp); |
3262 | } | 3261 | } |
3263 | 3262 | ||
3264 | cancel_delayed_work(&laundromat_work); | ||
3265 | nfsd4_shutdown_recdir(); | 3263 | nfsd4_shutdown_recdir(); |
3266 | nfs4_init = 0; | 3264 | nfs4_init = 0; |
3267 | } | 3265 | } |
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index c2660cbfcd96..8d995bcef806 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/stat.h> | 17 | #include <linux/stat.h> |
18 | #include <linux/dcache.h> | 18 | #include <linux/dcache.h> |
19 | #include <linux/mount.h> | 19 | #include <linux/mount.h> |
20 | #include <asm/pgtable.h> | ||
21 | 20 | ||
22 | #include <linux/sunrpc/clnt.h> | 21 | #include <linux/sunrpc/clnt.h> |
23 | #include <linux/sunrpc/svc.h> | 22 | #include <linux/sunrpc/svc.h> |
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 93628b02ef5d..875c11443817 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
@@ -614,6 +614,27 @@ static void ocfs2_dio_end_io(struct kiocb *iocb, | |||
614 | ocfs2_rw_unlock(inode, 0); | 614 | ocfs2_rw_unlock(inode, 0); |
615 | } | 615 | } |
616 | 616 | ||
617 | /* | ||
618 | * ocfs2_invalidatepage() and ocfs2_releasepage() are shamelessly stolen | ||
619 | * from ext3. PageChecked() bits have been removed as OCFS2 does not | ||
620 | * do journalled data. | ||
621 | */ | ||
622 | static void ocfs2_invalidatepage(struct page *page, unsigned long offset) | ||
623 | { | ||
624 | journal_t *journal = OCFS2_SB(page->mapping->host->i_sb)->journal->j_journal; | ||
625 | |||
626 | journal_invalidatepage(journal, page, offset); | ||
627 | } | ||
628 | |||
629 | static int ocfs2_releasepage(struct page *page, gfp_t wait) | ||
630 | { | ||
631 | journal_t *journal = OCFS2_SB(page->mapping->host->i_sb)->journal->j_journal; | ||
632 | |||
633 | if (!page_has_buffers(page)) | ||
634 | return 0; | ||
635 | return journal_try_to_free_buffers(journal, page, wait); | ||
636 | } | ||
637 | |||
617 | static ssize_t ocfs2_direct_IO(int rw, | 638 | static ssize_t ocfs2_direct_IO(int rw, |
618 | struct kiocb *iocb, | 639 | struct kiocb *iocb, |
619 | const struct iovec *iov, | 640 | const struct iovec *iov, |
@@ -661,5 +682,8 @@ const struct address_space_operations ocfs2_aops = { | |||
661 | .commit_write = ocfs2_commit_write, | 682 | .commit_write = ocfs2_commit_write, |
662 | .bmap = ocfs2_bmap, | 683 | .bmap = ocfs2_bmap, |
663 | .sync_page = block_sync_page, | 684 | .sync_page = block_sync_page, |
664 | .direct_IO = ocfs2_direct_IO | 685 | .direct_IO = ocfs2_direct_IO, |
686 | .invalidatepage = ocfs2_invalidatepage, | ||
687 | .releasepage = ocfs2_releasepage, | ||
688 | .migratepage = buffer_migrate_page, | ||
665 | }; | 689 | }; |
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index 5a9779bb9236..eba282da500e 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c | |||
@@ -1234,6 +1234,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, | |||
1234 | const char *page, | 1234 | const char *page, |
1235 | size_t count) | 1235 | size_t count) |
1236 | { | 1236 | { |
1237 | struct task_struct *hb_task; | ||
1237 | long fd; | 1238 | long fd; |
1238 | int sectsize; | 1239 | int sectsize; |
1239 | char *p = (char *)page; | 1240 | char *p = (char *)page; |
@@ -1319,20 +1320,28 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, | |||
1319 | */ | 1320 | */ |
1320 | atomic_set(®->hr_steady_iterations, O2HB_LIVE_THRESHOLD + 1); | 1321 | atomic_set(®->hr_steady_iterations, O2HB_LIVE_THRESHOLD + 1); |
1321 | 1322 | ||
1322 | reg->hr_task = kthread_run(o2hb_thread, reg, "o2hb-%s", | 1323 | hb_task = kthread_run(o2hb_thread, reg, "o2hb-%s", |
1323 | reg->hr_item.ci_name); | 1324 | reg->hr_item.ci_name); |
1324 | if (IS_ERR(reg->hr_task)) { | 1325 | if (IS_ERR(hb_task)) { |
1325 | ret = PTR_ERR(reg->hr_task); | 1326 | ret = PTR_ERR(hb_task); |
1326 | mlog_errno(ret); | 1327 | mlog_errno(ret); |
1327 | reg->hr_task = NULL; | ||
1328 | goto out; | 1328 | goto out; |
1329 | } | 1329 | } |
1330 | 1330 | ||
1331 | spin_lock(&o2hb_live_lock); | ||
1332 | reg->hr_task = hb_task; | ||
1333 | spin_unlock(&o2hb_live_lock); | ||
1334 | |||
1331 | ret = wait_event_interruptible(o2hb_steady_queue, | 1335 | ret = wait_event_interruptible(o2hb_steady_queue, |
1332 | atomic_read(®->hr_steady_iterations) == 0); | 1336 | atomic_read(®->hr_steady_iterations) == 0); |
1333 | if (ret) { | 1337 | if (ret) { |
1334 | kthread_stop(reg->hr_task); | 1338 | spin_lock(&o2hb_live_lock); |
1339 | hb_task = reg->hr_task; | ||
1335 | reg->hr_task = NULL; | 1340 | reg->hr_task = NULL; |
1341 | spin_unlock(&o2hb_live_lock); | ||
1342 | |||
1343 | if (hb_task) | ||
1344 | kthread_stop(hb_task); | ||
1336 | goto out; | 1345 | goto out; |
1337 | } | 1346 | } |
1338 | 1347 | ||
@@ -1354,10 +1363,17 @@ out: | |||
1354 | static ssize_t o2hb_region_pid_read(struct o2hb_region *reg, | 1363 | static ssize_t o2hb_region_pid_read(struct o2hb_region *reg, |
1355 | char *page) | 1364 | char *page) |
1356 | { | 1365 | { |
1357 | if (!reg->hr_task) | 1366 | pid_t pid = 0; |
1367 | |||
1368 | spin_lock(&o2hb_live_lock); | ||
1369 | if (reg->hr_task) | ||
1370 | pid = reg->hr_task->pid; | ||
1371 | spin_unlock(&o2hb_live_lock); | ||
1372 | |||
1373 | if (!pid) | ||
1358 | return 0; | 1374 | return 0; |
1359 | 1375 | ||
1360 | return sprintf(page, "%u\n", reg->hr_task->pid); | 1376 | return sprintf(page, "%u\n", pid); |
1361 | } | 1377 | } |
1362 | 1378 | ||
1363 | struct o2hb_region_attribute { | 1379 | struct o2hb_region_attribute { |
@@ -1495,13 +1511,17 @@ out: | |||
1495 | static void o2hb_heartbeat_group_drop_item(struct config_group *group, | 1511 | static void o2hb_heartbeat_group_drop_item(struct config_group *group, |
1496 | struct config_item *item) | 1512 | struct config_item *item) |
1497 | { | 1513 | { |
1514 | struct task_struct *hb_task; | ||
1498 | struct o2hb_region *reg = to_o2hb_region(item); | 1515 | struct o2hb_region *reg = to_o2hb_region(item); |
1499 | 1516 | ||
1500 | /* stop the thread when the user removes the region dir */ | 1517 | /* stop the thread when the user removes the region dir */ |
1501 | if (reg->hr_task) { | 1518 | spin_lock(&o2hb_live_lock); |
1502 | kthread_stop(reg->hr_task); | 1519 | hb_task = reg->hr_task; |
1503 | reg->hr_task = NULL; | 1520 | reg->hr_task = NULL; |
1504 | } | 1521 | spin_unlock(&o2hb_live_lock); |
1522 | |||
1523 | if (hb_task) | ||
1524 | kthread_stop(hb_task); | ||
1505 | 1525 | ||
1506 | config_item_put(item); | 1526 | config_item_put(item); |
1507 | } | 1527 | } |
@@ -1682,7 +1702,7 @@ out: | |||
1682 | } | 1702 | } |
1683 | EXPORT_SYMBOL_GPL(o2hb_register_callback); | 1703 | EXPORT_SYMBOL_GPL(o2hb_register_callback); |
1684 | 1704 | ||
1685 | int o2hb_unregister_callback(struct o2hb_callback_func *hc) | 1705 | void o2hb_unregister_callback(struct o2hb_callback_func *hc) |
1686 | { | 1706 | { |
1687 | BUG_ON(hc->hc_magic != O2HB_CB_MAGIC); | 1707 | BUG_ON(hc->hc_magic != O2HB_CB_MAGIC); |
1688 | 1708 | ||
@@ -1690,15 +1710,13 @@ int o2hb_unregister_callback(struct o2hb_callback_func *hc) | |||
1690 | __builtin_return_address(0), hc); | 1710 | __builtin_return_address(0), hc); |
1691 | 1711 | ||
1692 | if (list_empty(&hc->hc_item)) | 1712 | if (list_empty(&hc->hc_item)) |
1693 | return 0; | 1713 | return; |
1694 | 1714 | ||
1695 | down_write(&o2hb_callback_sem); | 1715 | down_write(&o2hb_callback_sem); |
1696 | 1716 | ||
1697 | list_del_init(&hc->hc_item); | 1717 | list_del_init(&hc->hc_item); |
1698 | 1718 | ||
1699 | up_write(&o2hb_callback_sem); | 1719 | up_write(&o2hb_callback_sem); |
1700 | |||
1701 | return 0; | ||
1702 | } | 1720 | } |
1703 | EXPORT_SYMBOL_GPL(o2hb_unregister_callback); | 1721 | EXPORT_SYMBOL_GPL(o2hb_unregister_callback); |
1704 | 1722 | ||
diff --git a/fs/ocfs2/cluster/heartbeat.h b/fs/ocfs2/cluster/heartbeat.h index cac6223206a9..cc6d40b39771 100644 --- a/fs/ocfs2/cluster/heartbeat.h +++ b/fs/ocfs2/cluster/heartbeat.h | |||
@@ -70,7 +70,7 @@ void o2hb_setup_callback(struct o2hb_callback_func *hc, | |||
70 | void *data, | 70 | void *data, |
71 | int priority); | 71 | int priority); |
72 | int o2hb_register_callback(struct o2hb_callback_func *hc); | 72 | int o2hb_register_callback(struct o2hb_callback_func *hc); |
73 | int o2hb_unregister_callback(struct o2hb_callback_func *hc); | 73 | void o2hb_unregister_callback(struct o2hb_callback_func *hc); |
74 | void o2hb_fill_node_map(unsigned long *map, | 74 | void o2hb_fill_node_map(unsigned long *map, |
75 | unsigned bytes); | 75 | unsigned bytes); |
76 | void o2hb_init(void); | 76 | void o2hb_init(void); |
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index 1718215fc018..69caf3e12fea 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c | |||
@@ -1638,17 +1638,8 @@ static void o2net_hb_node_up_cb(struct o2nm_node *node, int node_num, | |||
1638 | 1638 | ||
1639 | void o2net_unregister_hb_callbacks(void) | 1639 | void o2net_unregister_hb_callbacks(void) |
1640 | { | 1640 | { |
1641 | int ret; | 1641 | o2hb_unregister_callback(&o2net_hb_up); |
1642 | 1642 | o2hb_unregister_callback(&o2net_hb_down); | |
1643 | ret = o2hb_unregister_callback(&o2net_hb_up); | ||
1644 | if (ret < 0) | ||
1645 | mlog(ML_ERROR, "Status return %d unregistering heartbeat up " | ||
1646 | "callback!\n", ret); | ||
1647 | |||
1648 | ret = o2hb_unregister_callback(&o2net_hb_down); | ||
1649 | if (ret < 0) | ||
1650 | mlog(ML_ERROR, "Status return %d unregistering heartbeat down " | ||
1651 | "callback!\n", ret); | ||
1652 | } | 1643 | } |
1653 | 1644 | ||
1654 | int o2net_register_hb_callbacks(void) | 1645 | int o2net_register_hb_callbacks(void) |
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index 6087c4749fee..c558442a0b44 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c | |||
@@ -138,8 +138,10 @@ static void dlm_unregister_domain_handlers(struct dlm_ctxt *dlm); | |||
138 | 138 | ||
139 | void __dlm_unhash_lockres(struct dlm_lock_resource *lockres) | 139 | void __dlm_unhash_lockres(struct dlm_lock_resource *lockres) |
140 | { | 140 | { |
141 | hlist_del_init(&lockres->hash_node); | 141 | if (!hlist_unhashed(&lockres->hash_node)) { |
142 | dlm_lockres_put(lockres); | 142 | hlist_del_init(&lockres->hash_node); |
143 | dlm_lockres_put(lockres); | ||
144 | } | ||
143 | } | 145 | } |
144 | 146 | ||
145 | void __dlm_insert_lockres(struct dlm_ctxt *dlm, | 147 | void __dlm_insert_lockres(struct dlm_ctxt *dlm, |
@@ -655,6 +657,8 @@ void dlm_unregister_domain(struct dlm_ctxt *dlm) | |||
655 | dlm_kick_thread(dlm, NULL); | 657 | dlm_kick_thread(dlm, NULL); |
656 | 658 | ||
657 | while (dlm_migrate_all_locks(dlm)) { | 659 | while (dlm_migrate_all_locks(dlm)) { |
660 | /* Give dlm_thread time to purge the lockres' */ | ||
661 | msleep(500); | ||
658 | mlog(0, "%s: more migration to do\n", dlm->name); | 662 | mlog(0, "%s: more migration to do\n", dlm->name); |
659 | } | 663 | } |
660 | dlm_mark_domain_leaving(dlm); | 664 | dlm_mark_domain_leaving(dlm); |
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 77e4e6169a0d..6edffca99d98 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c | |||
@@ -2424,6 +2424,57 @@ static void dlm_deref_lockres_worker(struct dlm_work_item *item, void *data) | |||
2424 | dlm_lockres_put(res); | 2424 | dlm_lockres_put(res); |
2425 | } | 2425 | } |
2426 | 2426 | ||
2427 | /* Checks whether the lockres can be migrated. Returns 0 if yes, < 0 | ||
2428 | * if not. If 0, numlocks is set to the number of locks in the lockres. | ||
2429 | */ | ||
2430 | static int dlm_is_lockres_migrateable(struct dlm_ctxt *dlm, | ||
2431 | struct dlm_lock_resource *res, | ||
2432 | int *numlocks) | ||
2433 | { | ||
2434 | int ret; | ||
2435 | int i; | ||
2436 | int count = 0; | ||
2437 | struct list_head *queue, *iter; | ||
2438 | struct dlm_lock *lock; | ||
2439 | |||
2440 | assert_spin_locked(&res->spinlock); | ||
2441 | |||
2442 | ret = -EINVAL; | ||
2443 | if (res->owner == DLM_LOCK_RES_OWNER_UNKNOWN) { | ||
2444 | mlog(0, "cannot migrate lockres with unknown owner!\n"); | ||
2445 | goto leave; | ||
2446 | } | ||
2447 | |||
2448 | if (res->owner != dlm->node_num) { | ||
2449 | mlog(0, "cannot migrate lockres this node doesn't own!\n"); | ||
2450 | goto leave; | ||
2451 | } | ||
2452 | |||
2453 | ret = 0; | ||
2454 | queue = &res->granted; | ||
2455 | for (i = 0; i < 3; i++) { | ||
2456 | list_for_each(iter, queue) { | ||
2457 | lock = list_entry(iter, struct dlm_lock, list); | ||
2458 | ++count; | ||
2459 | if (lock->ml.node == dlm->node_num) { | ||
2460 | mlog(0, "found a lock owned by this node still " | ||
2461 | "on the %s queue! will not migrate this " | ||
2462 | "lockres\n", (i == 0 ? "granted" : | ||
2463 | (i == 1 ? "converting" : | ||
2464 | "blocked"))); | ||
2465 | ret = -ENOTEMPTY; | ||
2466 | goto leave; | ||
2467 | } | ||
2468 | } | ||
2469 | queue++; | ||
2470 | } | ||
2471 | |||
2472 | *numlocks = count; | ||
2473 | mlog(0, "migrateable lockres having %d locks\n", *numlocks); | ||
2474 | |||
2475 | leave: | ||
2476 | return ret; | ||
2477 | } | ||
2427 | 2478 | ||
2428 | /* | 2479 | /* |
2429 | * DLM_MIGRATE_LOCKRES | 2480 | * DLM_MIGRATE_LOCKRES |
@@ -2437,14 +2488,12 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm, | |||
2437 | struct dlm_master_list_entry *mle = NULL; | 2488 | struct dlm_master_list_entry *mle = NULL; |
2438 | struct dlm_master_list_entry *oldmle = NULL; | 2489 | struct dlm_master_list_entry *oldmle = NULL; |
2439 | struct dlm_migratable_lockres *mres = NULL; | 2490 | struct dlm_migratable_lockres *mres = NULL; |
2440 | int ret = -EINVAL; | 2491 | int ret = 0; |
2441 | const char *name; | 2492 | const char *name; |
2442 | unsigned int namelen; | 2493 | unsigned int namelen; |
2443 | int mle_added = 0; | 2494 | int mle_added = 0; |
2444 | struct list_head *queue, *iter; | 2495 | int numlocks; |
2445 | int i; | 2496 | int wake = 0; |
2446 | struct dlm_lock *lock; | ||
2447 | int empty = 1, wake = 0; | ||
2448 | 2497 | ||
2449 | if (!dlm_grab(dlm)) | 2498 | if (!dlm_grab(dlm)) |
2450 | return -EINVAL; | 2499 | return -EINVAL; |
@@ -2458,42 +2507,16 @@ static int dlm_migrate_lockres(struct dlm_ctxt *dlm, | |||
2458 | * ensure this lockres is a proper candidate for migration | 2507 | * ensure this lockres is a proper candidate for migration |
2459 | */ | 2508 | */ |
2460 | spin_lock(&res->spinlock); | 2509 | spin_lock(&res->spinlock); |
2461 | if (res->owner == DLM_LOCK_RES_OWNER_UNKNOWN) { | 2510 | ret = dlm_is_lockres_migrateable(dlm, res, &numlocks); |
2462 | mlog(0, "cannot migrate lockres with unknown owner!\n"); | 2511 | if (ret < 0) { |
2463 | spin_unlock(&res->spinlock); | ||
2464 | goto leave; | ||
2465 | } | ||
2466 | if (res->owner != dlm->node_num) { | ||
2467 | mlog(0, "cannot migrate lockres this node doesn't own!\n"); | ||
2468 | spin_unlock(&res->spinlock); | 2512 | spin_unlock(&res->spinlock); |
2469 | goto leave; | 2513 | goto leave; |
2470 | } | 2514 | } |
2471 | mlog(0, "checking queues...\n"); | ||
2472 | queue = &res->granted; | ||
2473 | for (i=0; i<3; i++) { | ||
2474 | list_for_each(iter, queue) { | ||
2475 | lock = list_entry (iter, struct dlm_lock, list); | ||
2476 | empty = 0; | ||
2477 | if (lock->ml.node == dlm->node_num) { | ||
2478 | mlog(0, "found a lock owned by this node " | ||
2479 | "still on the %s queue! will not " | ||
2480 | "migrate this lockres\n", | ||
2481 | i==0 ? "granted" : | ||
2482 | (i==1 ? "converting" : "blocked")); | ||
2483 | spin_unlock(&res->spinlock); | ||
2484 | ret = -ENOTEMPTY; | ||
2485 | goto leave; | ||
2486 | } | ||
2487 | } | ||
2488 | queue++; | ||
2489 | } | ||
2490 | mlog(0, "all locks on this lockres are nonlocal. continuing\n"); | ||
2491 | spin_unlock(&res->spinlock); | 2515 | spin_unlock(&res->spinlock); |
2492 | 2516 | ||
2493 | /* no work to do */ | 2517 | /* no work to do */ |
2494 | if (empty) { | 2518 | if (numlocks == 0) { |
2495 | mlog(0, "no locks were found on this lockres! done!\n"); | 2519 | mlog(0, "no locks were found on this lockres! done!\n"); |
2496 | ret = 0; | ||
2497 | goto leave; | 2520 | goto leave; |
2498 | } | 2521 | } |
2499 | 2522 | ||
@@ -2729,15 +2752,26 @@ int dlm_empty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res) | |||
2729 | { | 2752 | { |
2730 | int ret; | 2753 | int ret; |
2731 | int lock_dropped = 0; | 2754 | int lock_dropped = 0; |
2755 | int numlocks; | ||
2732 | 2756 | ||
2757 | spin_lock(&res->spinlock); | ||
2733 | if (res->owner != dlm->node_num) { | 2758 | if (res->owner != dlm->node_num) { |
2734 | if (!__dlm_lockres_unused(res)) { | 2759 | if (!__dlm_lockres_unused(res)) { |
2735 | mlog(ML_ERROR, "%s:%.*s: this node is not master, " | 2760 | mlog(ML_ERROR, "%s:%.*s: this node is not master, " |
2736 | "trying to free this but locks remain\n", | 2761 | "trying to free this but locks remain\n", |
2737 | dlm->name, res->lockname.len, res->lockname.name); | 2762 | dlm->name, res->lockname.len, res->lockname.name); |
2738 | } | 2763 | } |
2764 | spin_unlock(&res->spinlock); | ||
2765 | goto leave; | ||
2766 | } | ||
2767 | |||
2768 | /* No need to migrate a lockres having no locks */ | ||
2769 | ret = dlm_is_lockres_migrateable(dlm, res, &numlocks); | ||
2770 | if (ret >= 0 && numlocks == 0) { | ||
2771 | spin_unlock(&res->spinlock); | ||
2739 | goto leave; | 2772 | goto leave; |
2740 | } | 2773 | } |
2774 | spin_unlock(&res->spinlock); | ||
2741 | 2775 | ||
2742 | /* Wheee! Migrate lockres here! Will sleep so drop spinlock. */ | 2776 | /* Wheee! Migrate lockres here! Will sleep so drop spinlock. */ |
2743 | spin_unlock(&dlm->spinlock); | 2777 | spin_unlock(&dlm->spinlock); |
diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c index 8ffa0916eb86..2b264c6ba039 100644 --- a/fs/ocfs2/dlm/dlmthread.c +++ b/fs/ocfs2/dlm/dlmthread.c | |||
@@ -256,18 +256,14 @@ static void dlm_run_purge_list(struct dlm_ctxt *dlm, | |||
256 | break; | 256 | break; |
257 | } | 257 | } |
258 | 258 | ||
259 | mlog(0, "removing lockres %.*s:%p from purgelist\n", | 259 | dlm_lockres_get(lockres); |
260 | lockres->lockname.len, lockres->lockname.name, lockres); | ||
261 | list_del_init(&lockres->purge); | ||
262 | dlm_lockres_put(lockres); | ||
263 | dlm->purge_count--; | ||
264 | 260 | ||
265 | /* This may drop and reacquire the dlm spinlock if it | 261 | /* This may drop and reacquire the dlm spinlock if it |
266 | * has to do migration. */ | 262 | * has to do migration. */ |
267 | mlog(0, "calling dlm_purge_lockres!\n"); | ||
268 | if (dlm_purge_lockres(dlm, lockres)) | 263 | if (dlm_purge_lockres(dlm, lockres)) |
269 | BUG(); | 264 | BUG(); |
270 | mlog(0, "DONE calling dlm_purge_lockres!\n"); | 265 | |
266 | dlm_lockres_put(lockres); | ||
271 | 267 | ||
272 | /* Avoid adding any scheduling latencies */ | 268 | /* Avoid adding any scheduling latencies */ |
273 | cond_resched_lock(&dlm->spinlock); | 269 | cond_resched_lock(&dlm->spinlock); |
diff --git a/fs/ocfs2/heartbeat.c b/fs/ocfs2/heartbeat.c index 8fc52d6d0ce7..b25ef63781ba 100644 --- a/fs/ocfs2/heartbeat.c +++ b/fs/ocfs2/heartbeat.c | |||
@@ -164,8 +164,10 @@ int ocfs2_register_hb_callbacks(struct ocfs2_super *osb) | |||
164 | } | 164 | } |
165 | 165 | ||
166 | status = o2hb_register_callback(&osb->osb_hb_up); | 166 | status = o2hb_register_callback(&osb->osb_hb_up); |
167 | if (status < 0) | 167 | if (status < 0) { |
168 | mlog_errno(status); | 168 | mlog_errno(status); |
169 | o2hb_unregister_callback(&osb->osb_hb_down); | ||
170 | } | ||
169 | 171 | ||
170 | bail: | 172 | bail: |
171 | return status; | 173 | return status; |
@@ -173,18 +175,11 @@ bail: | |||
173 | 175 | ||
174 | void ocfs2_clear_hb_callbacks(struct ocfs2_super *osb) | 176 | void ocfs2_clear_hb_callbacks(struct ocfs2_super *osb) |
175 | { | 177 | { |
176 | int status; | ||
177 | |||
178 | if (ocfs2_mount_local(osb)) | 178 | if (ocfs2_mount_local(osb)) |
179 | return; | 179 | return; |
180 | 180 | ||
181 | status = o2hb_unregister_callback(&osb->osb_hb_down); | 181 | o2hb_unregister_callback(&osb->osb_hb_down); |
182 | if (status < 0) | 182 | o2hb_unregister_callback(&osb->osb_hb_up); |
183 | mlog_errno(status); | ||
184 | |||
185 | status = o2hb_unregister_callback(&osb->osb_hb_up); | ||
186 | if (status < 0) | ||
187 | mlog_errno(status); | ||
188 | } | 183 | } |
189 | 184 | ||
190 | void ocfs2_stop_heartbeat(struct ocfs2_super *osb) | 185 | void ocfs2_stop_heartbeat(struct ocfs2_super *osb) |
diff --git a/fs/partitions/Kconfig b/fs/partitions/Kconfig index 74552c60b671..6e8bb66fe619 100644 --- a/fs/partitions/Kconfig +++ b/fs/partitions/Kconfig | |||
@@ -235,5 +235,4 @@ config EFI_PARTITION | |||
235 | select CRC32 | 235 | select CRC32 |
236 | help | 236 | help |
237 | Say Y here if you would like to use hard disks under Linux which | 237 | Say Y here if you would like to use hard disks under Linux which |
238 | were partitioned using EFI GPT. Presently only useful on the | 238 | were partitioned using EFI GPT. |
239 | IA-64 platform. | ||
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 22d38ffc9ef0..8a7d0035ad7a 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) |
@@ -541,7 +541,7 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev) | |||
541 | if (!get_capacity(disk) || !(state = check_partition(disk, bdev))) | 541 | if (!get_capacity(disk) || !(state = check_partition(disk, bdev))) |
542 | return 0; | 542 | return 0; |
543 | if (IS_ERR(state)) /* I/O error reading the partition table */ | 543 | if (IS_ERR(state)) /* I/O error reading the partition table */ |
544 | return PTR_ERR(state); | 544 | return -EIO; |
545 | for (p = 1; p < state->limit; p++) { | 545 | for (p = 1; p < state->limit; p++) { |
546 | sector_t size = state->parts[p].size; | 546 | sector_t size = state->parts[p].size; |
547 | sector_t from = state->parts[p].from; | 547 | sector_t from = state->parts[p].from; |
diff --git a/fs/proc/Makefile b/fs/proc/Makefile index a6b3a8f878f0..bce38e3f06cb 100644 --- a/fs/proc/Makefile +++ b/fs/proc/Makefile | |||
@@ -8,8 +8,9 @@ proc-y := nommu.o task_nommu.o | |||
8 | proc-$(CONFIG_MMU) := mmu.o task_mmu.o | 8 | proc-$(CONFIG_MMU) := mmu.o task_mmu.o |
9 | 9 | ||
10 | proc-y += inode.o root.o base.o generic.o array.o \ | 10 | proc-y += inode.o root.o base.o generic.o array.o \ |
11 | proc_tty.o proc_misc.o proc_sysctl.o | 11 | proc_tty.o proc_misc.o |
12 | 12 | ||
13 | proc-$(CONFIG_PROC_SYSCTL) += proc_sysctl.o | ||
13 | proc-$(CONFIG_PROC_KCORE) += kcore.o | 14 | proc-$(CONFIG_PROC_KCORE) += kcore.o |
14 | proc-$(CONFIG_PROC_VMCORE) += vmcore.o | 15 | proc-$(CONFIG_PROC_VMCORE) += vmcore.o |
15 | proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o | 16 | proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 01f7769da8e6..989af5e55d1b 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -1558,29 +1558,20 @@ static ssize_t proc_pid_attr_read(struct file * file, char __user * buf, | |||
1558 | size_t count, loff_t *ppos) | 1558 | size_t count, loff_t *ppos) |
1559 | { | 1559 | { |
1560 | struct inode * inode = file->f_path.dentry->d_inode; | 1560 | struct inode * inode = file->f_path.dentry->d_inode; |
1561 | unsigned long page; | 1561 | char *p = NULL; |
1562 | ssize_t length; | 1562 | ssize_t length; |
1563 | struct task_struct *task = get_proc_task(inode); | 1563 | struct task_struct *task = get_proc_task(inode); |
1564 | 1564 | ||
1565 | length = -ESRCH; | ||
1566 | if (!task) | 1565 | if (!task) |
1567 | goto out_no_task; | 1566 | return -ESRCH; |
1568 | |||
1569 | if (count > PAGE_SIZE) | ||
1570 | count = PAGE_SIZE; | ||
1571 | length = -ENOMEM; | ||
1572 | if (!(page = __get_free_page(GFP_KERNEL))) | ||
1573 | goto out; | ||
1574 | 1567 | ||
1575 | length = security_getprocattr(task, | 1568 | length = security_getprocattr(task, |
1576 | (char*)file->f_path.dentry->d_name.name, | 1569 | (char*)file->f_path.dentry->d_name.name, |
1577 | (void*)page, count); | 1570 | &p); |
1578 | if (length >= 0) | ||
1579 | length = simple_read_from_buffer(buf, count, ppos, (char *)page, length); | ||
1580 | free_page(page); | ||
1581 | out: | ||
1582 | put_task_struct(task); | 1571 | put_task_struct(task); |
1583 | out_no_task: | 1572 | if (length > 0) |
1573 | length = simple_read_from_buffer(buf, count, ppos, p, length); | ||
1574 | kfree(p); | ||
1584 | return length; | 1575 | return length; |
1585 | } | 1576 | } |
1586 | 1577 | ||
diff --git a/fs/proc/internal.h b/fs/proc/internal.h index c932aa65e198..f771889183c3 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h | |||
@@ -11,7 +11,11 @@ | |||
11 | 11 | ||
12 | #include <linux/proc_fs.h> | 12 | #include <linux/proc_fs.h> |
13 | 13 | ||
14 | #ifdef CONFIG_PROC_SYSCTL | ||
14 | extern int proc_sys_init(void); | 15 | extern int proc_sys_init(void); |
16 | #else | ||
17 | static inline void proc_sys_init(void) { } | ||
18 | #endif | ||
15 | 19 | ||
16 | struct vmalloc_info { | 20 | struct vmalloc_info { |
17 | unsigned long used; | 21 | unsigned long used; |
diff --git a/fs/proc/root.c b/fs/proc/root.c index 5834a744c2a9..41f17037f738 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c | |||
@@ -79,9 +79,7 @@ void __init proc_root_init(void) | |||
79 | proc_device_tree_init(); | 79 | proc_device_tree_init(); |
80 | #endif | 80 | #endif |
81 | proc_bus = proc_mkdir("bus", NULL); | 81 | proc_bus = proc_mkdir("bus", NULL); |
82 | #ifdef CONFIG_SYSCTL | ||
83 | proc_sys_init(); | 82 | proc_sys_init(); |
84 | #endif | ||
85 | } | 83 | } |
86 | 84 | ||
87 | static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat | 85 | static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat |
diff --git a/fs/smbfs/request.c b/fs/smbfs/request.c index 42261dbdf60f..723f7c667661 100644 --- a/fs/smbfs/request.c +++ b/fs/smbfs/request.c | |||
@@ -181,6 +181,7 @@ static int smb_setup_request(struct smb_request *req) | |||
181 | req->rq_errno = 0; | 181 | req->rq_errno = 0; |
182 | req->rq_fragment = 0; | 182 | req->rq_fragment = 0; |
183 | kfree(req->rq_trans2buffer); | 183 | kfree(req->rq_trans2buffer); |
184 | req->rq_trans2buffer = NULL; | ||
184 | 185 | ||
185 | return 0; | 186 | return 0; |
186 | } | 187 | } |
diff --git a/fs/splice.c b/fs/splice.c index 2fca6ebf4cc2..5428b0ff3b6f 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -576,76 +576,21 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, | |||
576 | if (this_len + offset > PAGE_CACHE_SIZE) | 576 | if (this_len + offset > PAGE_CACHE_SIZE) |
577 | this_len = PAGE_CACHE_SIZE - offset; | 577 | this_len = PAGE_CACHE_SIZE - offset; |
578 | 578 | ||
579 | /* | ||
580 | * Reuse buf page, if SPLICE_F_MOVE is set and we are doing a full | ||
581 | * page. | ||
582 | */ | ||
583 | if ((sd->flags & SPLICE_F_MOVE) && this_len == PAGE_CACHE_SIZE) { | ||
584 | /* | ||
585 | * If steal succeeds, buf->page is now pruned from the | ||
586 | * pagecache and we can reuse it. The page will also be | ||
587 | * locked on successful return. | ||
588 | */ | ||
589 | if (buf->ops->steal(pipe, buf)) | ||
590 | goto find_page; | ||
591 | |||
592 | page = buf->page; | ||
593 | if (add_to_page_cache(page, mapping, index, GFP_KERNEL)) { | ||
594 | unlock_page(page); | ||
595 | goto find_page; | ||
596 | } | ||
597 | |||
598 | page_cache_get(page); | ||
599 | |||
600 | if (!(buf->flags & PIPE_BUF_FLAG_LRU)) | ||
601 | lru_cache_add(page); | ||
602 | } else { | ||
603 | find_page: | 579 | find_page: |
604 | page = find_lock_page(mapping, index); | 580 | page = find_lock_page(mapping, index); |
605 | if (!page) { | 581 | if (!page) { |
606 | ret = -ENOMEM; | 582 | ret = -ENOMEM; |
607 | page = page_cache_alloc_cold(mapping); | 583 | page = page_cache_alloc_cold(mapping); |
608 | if (unlikely(!page)) | 584 | if (unlikely(!page)) |
609 | goto out_ret; | 585 | goto out_ret; |
610 | |||
611 | /* | ||
612 | * This will also lock the page | ||
613 | */ | ||
614 | ret = add_to_page_cache_lru(page, mapping, index, | ||
615 | GFP_KERNEL); | ||
616 | if (unlikely(ret)) | ||
617 | goto out; | ||
618 | } | ||
619 | 586 | ||
620 | /* | 587 | /* |
621 | * We get here with the page locked. If the page is also | 588 | * This will also lock the page |
622 | * uptodate, we don't need to do more. If it isn't, we | ||
623 | * may need to bring it in if we are not going to overwrite | ||
624 | * the full page. | ||
625 | */ | 589 | */ |
626 | if (!PageUptodate(page)) { | 590 | ret = add_to_page_cache_lru(page, mapping, index, |
627 | if (this_len < PAGE_CACHE_SIZE) { | 591 | GFP_KERNEL); |
628 | ret = mapping->a_ops->readpage(file, page); | 592 | if (unlikely(ret)) |
629 | if (unlikely(ret)) | 593 | goto out; |
630 | goto out; | ||
631 | |||
632 | lock_page(page); | ||
633 | |||
634 | if (!PageUptodate(page)) { | ||
635 | /* | ||
636 | * Page got invalidated, repeat. | ||
637 | */ | ||
638 | if (!page->mapping) { | ||
639 | unlock_page(page); | ||
640 | page_cache_release(page); | ||
641 | goto find_page; | ||
642 | } | ||
643 | ret = -EIO; | ||
644 | goto out; | ||
645 | } | ||
646 | } else | ||
647 | SetPageUptodate(page); | ||
648 | } | ||
649 | } | 594 | } |
650 | 595 | ||
651 | ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len); | 596 | ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len); |
@@ -682,18 +627,25 @@ find_page: | |||
682 | } | 627 | } |
683 | 628 | ||
684 | ret = mapping->a_ops->commit_write(file, page, offset, offset+this_len); | 629 | ret = mapping->a_ops->commit_write(file, page, offset, offset+this_len); |
685 | if (!ret) { | 630 | if (ret) { |
631 | if (ret == AOP_TRUNCATED_PAGE) { | ||
632 | page_cache_release(page); | ||
633 | goto find_page; | ||
634 | } | ||
635 | if (ret < 0) | ||
636 | goto out; | ||
686 | /* | 637 | /* |
687 | * Return the number of bytes written and mark page as | 638 | * Partial write has happened, so 'ret' already initialized by |
688 | * accessed, we are now done! | 639 | * number of bytes written, Where is nothing we have to do here. |
689 | */ | 640 | */ |
641 | } else | ||
690 | ret = this_len; | 642 | ret = this_len; |
691 | mark_page_accessed(page); | 643 | /* |
692 | balance_dirty_pages_ratelimited(mapping); | 644 | * Return the number of bytes written and mark page as |
693 | } else if (ret == AOP_TRUNCATED_PAGE) { | 645 | * accessed, we are now done! |
694 | page_cache_release(page); | 646 | */ |
695 | goto find_page; | 647 | mark_page_accessed(page); |
696 | } | 648 | balance_dirty_pages_ratelimited(mapping); |
697 | out: | 649 | out: |
698 | page_cache_release(page); | 650 | page_cache_release(page); |
699 | unlock_page(page); | 651 | unlock_page(page); |
@@ -706,9 +658,9 @@ out_ret: | |||
706 | * key here is the 'actor' worker passed in that actually moves the data | 658 | * key here is the 'actor' worker passed in that actually moves the data |
707 | * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. | 659 | * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. |
708 | */ | 660 | */ |
709 | static ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, | 661 | ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, |
710 | struct file *out, loff_t *ppos, size_t len, | 662 | struct file *out, loff_t *ppos, size_t len, |
711 | unsigned int flags, splice_actor *actor) | 663 | unsigned int flags, splice_actor *actor) |
712 | { | 664 | { |
713 | int ret, do_wakeup, err; | 665 | int ret, do_wakeup, err; |
714 | struct splice_desc sd; | 666 | struct splice_desc sd; |
@@ -802,6 +754,7 @@ static ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, | |||
802 | 754 | ||
803 | return ret; | 755 | return ret; |
804 | } | 756 | } |
757 | EXPORT_SYMBOL(__splice_from_pipe); | ||
805 | 758 | ||
806 | ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, | 759 | ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, |
807 | loff_t *ppos, size_t len, unsigned int flags, | 760 | loff_t *ppos, size_t len, unsigned int flags, |
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 8d4d839a9d88..fc4633378dc0 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -168,12 +168,12 @@ sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |||
168 | ssize_t retval = 0; | 168 | ssize_t retval = 0; |
169 | 169 | ||
170 | down(&buffer->sem); | 170 | down(&buffer->sem); |
171 | if (buffer->orphaned) { | ||
172 | retval = -ENODEV; | ||
173 | goto out; | ||
174 | } | ||
175 | if (buffer->needs_read_fill) { | 171 | if (buffer->needs_read_fill) { |
176 | if ((retval = fill_read_buffer(file->f_path.dentry,buffer))) | 172 | if (buffer->orphaned) |
173 | retval = -ENODEV; | ||
174 | else | ||
175 | retval = fill_read_buffer(file->f_path.dentry,buffer); | ||
176 | if (retval) | ||
177 | goto out; | 177 | goto out; |
178 | } | 178 | } |
179 | pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n", | 179 | pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n", |
@@ -629,6 +629,60 @@ void sysfs_remove_file_from_group(struct kobject *kobj, | |||
629 | } | 629 | } |
630 | EXPORT_SYMBOL_GPL(sysfs_remove_file_from_group); | 630 | EXPORT_SYMBOL_GPL(sysfs_remove_file_from_group); |
631 | 631 | ||
632 | struct sysfs_schedule_callback_struct { | ||
633 | struct kobject *kobj; | ||
634 | void (*func)(void *); | ||
635 | void *data; | ||
636 | struct work_struct work; | ||
637 | }; | ||
638 | |||
639 | static void sysfs_schedule_callback_work(struct work_struct *work) | ||
640 | { | ||
641 | struct sysfs_schedule_callback_struct *ss = container_of(work, | ||
642 | struct sysfs_schedule_callback_struct, work); | ||
643 | |||
644 | (ss->func)(ss->data); | ||
645 | kobject_put(ss->kobj); | ||
646 | kfree(ss); | ||
647 | } | ||
648 | |||
649 | /** | ||
650 | * sysfs_schedule_callback - helper to schedule a callback for a kobject | ||
651 | * @kobj: object we're acting for. | ||
652 | * @func: callback function to invoke later. | ||
653 | * @data: argument to pass to @func. | ||
654 | * | ||
655 | * sysfs attribute methods must not unregister themselves or their parent | ||
656 | * kobject (which would amount to the same thing). Attempts to do so will | ||
657 | * deadlock, since unregistration is mutually exclusive with driver | ||
658 | * callbacks. | ||
659 | * | ||
660 | * Instead methods can call this routine, which will attempt to allocate | ||
661 | * and schedule a workqueue request to call back @func with @data as its | ||
662 | * argument in the workqueue's process context. @kobj will be pinned | ||
663 | * until @func returns. | ||
664 | * | ||
665 | * Returns 0 if the request was submitted, -ENOMEM if storage could not | ||
666 | * be allocated. | ||
667 | */ | ||
668 | int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *), | ||
669 | void *data) | ||
670 | { | ||
671 | struct sysfs_schedule_callback_struct *ss; | ||
672 | |||
673 | ss = kmalloc(sizeof(*ss), GFP_KERNEL); | ||
674 | if (!ss) | ||
675 | return -ENOMEM; | ||
676 | kobject_get(kobj); | ||
677 | ss->kobj = kobj; | ||
678 | ss->func = func; | ||
679 | ss->data = data; | ||
680 | INIT_WORK(&ss->work, sysfs_schedule_callback_work); | ||
681 | schedule_work(&ss->work); | ||
682 | return 0; | ||
683 | } | ||
684 | EXPORT_SYMBOL_GPL(sysfs_schedule_callback); | ||
685 | |||
632 | 686 | ||
633 | EXPORT_SYMBOL_GPL(sysfs_create_file); | 687 | EXPORT_SYMBOL_GPL(sysfs_create_file); |
634 | EXPORT_SYMBOL_GPL(sysfs_remove_file); | 688 | EXPORT_SYMBOL_GPL(sysfs_remove_file); |
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c index ccb7d722c558..4de5c6b89918 100644 --- a/fs/sysfs/inode.c +++ b/fs/sysfs/inode.c | |||
@@ -222,13 +222,17 @@ const unsigned char * sysfs_get_name(struct sysfs_dirent *sd) | |||
222 | 222 | ||
223 | static inline void orphan_all_buffers(struct inode *node) | 223 | static inline void orphan_all_buffers(struct inode *node) |
224 | { | 224 | { |
225 | struct sysfs_buffer_collection *set = node->i_private; | 225 | struct sysfs_buffer_collection *set; |
226 | struct sysfs_buffer *buf; | 226 | struct sysfs_buffer *buf; |
227 | 227 | ||
228 | mutex_lock_nested(&node->i_mutex, I_MUTEX_CHILD); | 228 | mutex_lock_nested(&node->i_mutex, I_MUTEX_CHILD); |
229 | if (node->i_private) { | 229 | set = node->i_private; |
230 | list_for_each_entry(buf, &set->associates, associates) | 230 | if (set) { |
231 | list_for_each_entry(buf, &set->associates, associates) { | ||
232 | down(&buf->sem); | ||
231 | buf->orphaned = 1; | 233 | buf->orphaned = 1; |
234 | up(&buf->sem); | ||
235 | } | ||
232 | } | 236 | } |
233 | mutex_unlock(&node->i_mutex); | 237 | mutex_unlock(&node->i_mutex); |
234 | } | 238 | } |
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c index bcc44084e004..841ac25fd950 100644 --- a/fs/ufs/balloc.c +++ b/fs/ufs/balloc.c | |||
@@ -244,62 +244,87 @@ failed: | |||
244 | * We can come here from ufs_writepage or ufs_prepare_write, | 244 | * We can come here from ufs_writepage or ufs_prepare_write, |
245 | * locked_page is argument of these functions, so we already lock it. | 245 | * locked_page is argument of these functions, so we already lock it. |
246 | */ | 246 | */ |
247 | static void ufs_change_blocknr(struct inode *inode, unsigned int beg, | 247 | static void ufs_change_blocknr(struct inode *inode, sector_t beg, |
248 | unsigned int count, unsigned int oldb, | 248 | unsigned int count, sector_t oldb, |
249 | unsigned int newb, struct page *locked_page) | 249 | sector_t newb, struct page *locked_page) |
250 | { | 250 | { |
251 | const unsigned mask = (1 << (PAGE_CACHE_SHIFT - inode->i_blkbits)) - 1; | 251 | const unsigned blks_per_page = |
252 | 1 << (PAGE_CACHE_SHIFT - inode->i_blkbits); | ||
253 | const unsigned mask = blks_per_page - 1; | ||
252 | struct address_space * const mapping = inode->i_mapping; | 254 | struct address_space * const mapping = inode->i_mapping; |
253 | pgoff_t index, cur_index; | 255 | pgoff_t index, cur_index, last_index; |
254 | unsigned end, pos, j; | 256 | unsigned pos, j, lblock; |
257 | sector_t end, i; | ||
255 | struct page *page; | 258 | struct page *page; |
256 | struct buffer_head *head, *bh; | 259 | struct buffer_head *head, *bh; |
257 | 260 | ||
258 | UFSD("ENTER, ino %lu, count %u, oldb %u, newb %u\n", | 261 | UFSD("ENTER, ino %lu, count %u, oldb %llu, newb %llu\n", |
259 | inode->i_ino, count, oldb, newb); | 262 | inode->i_ino, count, |
263 | (unsigned long long)oldb, (unsigned long long)newb); | ||
260 | 264 | ||
261 | BUG_ON(!locked_page); | 265 | BUG_ON(!locked_page); |
262 | BUG_ON(!PageLocked(locked_page)); | 266 | BUG_ON(!PageLocked(locked_page)); |
263 | 267 | ||
264 | cur_index = locked_page->index; | 268 | cur_index = locked_page->index; |
265 | 269 | end = count + beg; | |
266 | for (end = count + beg; beg < end; beg = (beg | mask) + 1) { | 270 | last_index = end >> (PAGE_CACHE_SHIFT - inode->i_blkbits); |
267 | index = beg >> (PAGE_CACHE_SHIFT - inode->i_blkbits); | 271 | for (i = beg; i < end; i = (i | mask) + 1) { |
272 | index = i >> (PAGE_CACHE_SHIFT - inode->i_blkbits); | ||
268 | 273 | ||
269 | if (likely(cur_index != index)) { | 274 | if (likely(cur_index != index)) { |
270 | page = ufs_get_locked_page(mapping, index); | 275 | page = ufs_get_locked_page(mapping, index); |
271 | if (!page || IS_ERR(page)) /* it was truncated or EIO */ | 276 | if (!page)/* it was truncated */ |
277 | continue; | ||
278 | if (IS_ERR(page)) {/* or EIO */ | ||
279 | ufs_error(inode->i_sb, __FUNCTION__, | ||
280 | "read of page %llu failed\n", | ||
281 | (unsigned long long)index); | ||
272 | continue; | 282 | continue; |
283 | } | ||
273 | } else | 284 | } else |
274 | page = locked_page; | 285 | page = locked_page; |
275 | 286 | ||
276 | head = page_buffers(page); | 287 | head = page_buffers(page); |
277 | bh = head; | 288 | bh = head; |
278 | pos = beg & mask; | 289 | pos = i & mask; |
279 | for (j = 0; j < pos; ++j) | 290 | for (j = 0; j < pos; ++j) |
280 | bh = bh->b_this_page; | 291 | bh = bh->b_this_page; |
281 | j = 0; | 292 | |
293 | |||
294 | if (unlikely(index == last_index)) | ||
295 | lblock = end & mask; | ||
296 | else | ||
297 | lblock = blks_per_page; | ||
298 | |||
282 | do { | 299 | do { |
283 | if (buffer_mapped(bh)) { | 300 | if (j >= lblock) |
284 | pos = bh->b_blocknr - oldb; | 301 | break; |
285 | if (pos < count) { | 302 | pos = (i - beg) + j; |
286 | UFSD(" change from %llu to %llu\n", | 303 | |
287 | (unsigned long long)pos + oldb, | 304 | if (!buffer_mapped(bh)) |
288 | (unsigned long long)pos + newb); | 305 | map_bh(bh, inode->i_sb, oldb + pos); |
289 | bh->b_blocknr = newb + pos; | 306 | if (!buffer_uptodate(bh)) { |
290 | unmap_underlying_metadata(bh->b_bdev, | 307 | ll_rw_block(READ, 1, &bh); |
291 | bh->b_blocknr); | 308 | wait_on_buffer(bh); |
292 | mark_buffer_dirty(bh); | 309 | if (!buffer_uptodate(bh)) { |
293 | ++j; | 310 | ufs_error(inode->i_sb, __FUNCTION__, |
311 | "read of block failed\n"); | ||
312 | break; | ||
294 | } | 313 | } |
295 | } | 314 | } |
296 | 315 | ||
316 | UFSD(" change from %llu to %llu, pos %u\n", | ||
317 | (unsigned long long)pos + oldb, | ||
318 | (unsigned long long)pos + newb, pos); | ||
319 | |||
320 | bh->b_blocknr = newb + pos; | ||
321 | unmap_underlying_metadata(bh->b_bdev, | ||
322 | bh->b_blocknr); | ||
323 | mark_buffer_dirty(bh); | ||
324 | ++j; | ||
297 | bh = bh->b_this_page; | 325 | bh = bh->b_this_page; |
298 | } while (bh != head); | 326 | } while (bh != head); |
299 | 327 | ||
300 | if (j) | ||
301 | set_page_dirty(page); | ||
302 | |||
303 | if (likely(cur_index != index)) | 328 | if (likely(cur_index != index)) |
304 | ufs_put_locked_page(page); | 329 | ufs_put_locked_page(page); |
305 | } | 330 | } |
@@ -457,8 +482,9 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, | |||
457 | if (result) { | 482 | if (result) { |
458 | ufs_clear_frags(inode, result + oldcount, newcount - oldcount, | 483 | ufs_clear_frags(inode, result + oldcount, newcount - oldcount, |
459 | locked_page != NULL); | 484 | locked_page != NULL); |
460 | ufs_change_blocknr(inode, fragment - oldcount, oldcount, tmp, | 485 | ufs_change_blocknr(inode, fragment - oldcount, oldcount, |
461 | result, locked_page); | 486 | uspi->s_sbbase + tmp, |
487 | uspi->s_sbbase + result, locked_page); | ||
462 | ufs_cpu_to_data_ptr(sb, p, result); | 488 | ufs_cpu_to_data_ptr(sb, p, result); |
463 | *err = 0; | 489 | *err = 0; |
464 | UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); | 490 | UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); |
diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c index b868878009b6..c28a8b6f2feb 100644 --- a/fs/ufs/ialloc.c +++ b/fs/ufs/ialloc.c | |||
@@ -343,9 +343,8 @@ cg_found: | |||
343 | lock_buffer(bh); | 343 | lock_buffer(bh); |
344 | ufs2_inode = (struct ufs2_inode *)bh->b_data; | 344 | ufs2_inode = (struct ufs2_inode *)bh->b_data; |
345 | ufs2_inode += ufs_inotofsbo(inode->i_ino); | 345 | ufs2_inode += ufs_inotofsbo(inode->i_ino); |
346 | ufs2_inode->ui_birthtime.tv_sec = | 346 | ufs2_inode->ui_birthtime = cpu_to_fs64(sb, CURRENT_TIME.tv_sec); |
347 | cpu_to_fs32(sb, CURRENT_TIME_SEC.tv_sec); | 347 | ufs2_inode->ui_birthnsec = cpu_to_fs32(sb, CURRENT_TIME.tv_nsec); |
348 | ufs2_inode->ui_birthtime.tv_usec = 0; | ||
349 | mark_buffer_dirty(bh); | 348 | mark_buffer_dirty(bh); |
350 | unlock_buffer(bh); | 349 | unlock_buffer(bh); |
351 | if (sb->s_flags & MS_SYNCHRONOUS) | 350 | if (sb->s_flags & MS_SYNCHRONOUS) |
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index fb34ad03e224..013d7afe7cde 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c | |||
@@ -212,7 +212,7 @@ repeat: | |||
212 | brelse (result); | 212 | brelse (result); |
213 | goto repeat; | 213 | goto repeat; |
214 | } else { | 214 | } else { |
215 | *phys = tmp + blockoff; | 215 | *phys = uspi->s_sbbase + tmp + blockoff; |
216 | return NULL; | 216 | return NULL; |
217 | } | 217 | } |
218 | } | 218 | } |
@@ -282,9 +282,9 @@ repeat: | |||
282 | } | 282 | } |
283 | 283 | ||
284 | if (!phys) { | 284 | if (!phys) { |
285 | result = sb_getblk(sb, tmp + blockoff); | 285 | result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff); |
286 | } else { | 286 | } else { |
287 | *phys = tmp + blockoff; | 287 | *phys = uspi->s_sbbase + tmp + blockoff; |
288 | result = NULL; | 288 | result = NULL; |
289 | *err = 0; | 289 | *err = 0; |
290 | *new = 1; | 290 | *new = 1; |
@@ -368,7 +368,7 @@ repeat: | |||
368 | brelse (result); | 368 | brelse (result); |
369 | goto repeat; | 369 | goto repeat; |
370 | } else { | 370 | } else { |
371 | *phys = tmp + blockoff; | 371 | *phys = uspi->s_sbbase + tmp + blockoff; |
372 | goto out; | 372 | goto out; |
373 | } | 373 | } |
374 | } | 374 | } |
@@ -389,9 +389,9 @@ repeat: | |||
389 | 389 | ||
390 | 390 | ||
391 | if (!phys) { | 391 | if (!phys) { |
392 | result = sb_getblk(sb, tmp + blockoff); | 392 | result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff); |
393 | } else { | 393 | } else { |
394 | *phys = tmp + blockoff; | 394 | *phys = uspi->s_sbbase + tmp + blockoff; |
395 | *new = 1; | 395 | *new = 1; |
396 | } | 396 | } |
397 | 397 | ||
@@ -668,12 +668,12 @@ static void ufs2_read_inode(struct inode *inode, struct ufs2_inode *ufs2_inode) | |||
668 | inode->i_gid = fs32_to_cpu(sb, ufs2_inode->ui_gid); | 668 | inode->i_gid = fs32_to_cpu(sb, ufs2_inode->ui_gid); |
669 | 669 | ||
670 | inode->i_size = fs64_to_cpu(sb, ufs2_inode->ui_size); | 670 | inode->i_size = fs64_to_cpu(sb, ufs2_inode->ui_size); |
671 | inode->i_atime.tv_sec = fs32_to_cpu(sb, ufs2_inode->ui_atime.tv_sec); | 671 | inode->i_atime.tv_sec = fs64_to_cpu(sb, ufs2_inode->ui_atime); |
672 | inode->i_ctime.tv_sec = fs32_to_cpu(sb, ufs2_inode->ui_ctime.tv_sec); | 672 | inode->i_ctime.tv_sec = fs64_to_cpu(sb, ufs2_inode->ui_ctime); |
673 | inode->i_mtime.tv_sec = fs32_to_cpu(sb, ufs2_inode->ui_mtime.tv_sec); | 673 | inode->i_mtime.tv_sec = fs64_to_cpu(sb, ufs2_inode->ui_mtime); |
674 | inode->i_mtime.tv_nsec = 0; | 674 | inode->i_atime.tv_nsec = fs32_to_cpu(sb, ufs2_inode->ui_atimensec); |
675 | inode->i_atime.tv_nsec = 0; | 675 | inode->i_ctime.tv_nsec = fs32_to_cpu(sb, ufs2_inode->ui_ctimensec); |
676 | inode->i_ctime.tv_nsec = 0; | 676 | inode->i_mtime.tv_nsec = fs32_to_cpu(sb, ufs2_inode->ui_mtimensec); |
677 | inode->i_blocks = fs64_to_cpu(sb, ufs2_inode->ui_blocks); | 677 | inode->i_blocks = fs64_to_cpu(sb, ufs2_inode->ui_blocks); |
678 | inode->i_generation = fs32_to_cpu(sb, ufs2_inode->ui_gen); | 678 | inode->i_generation = fs32_to_cpu(sb, ufs2_inode->ui_gen); |
679 | ufsi->i_flags = fs32_to_cpu(sb, ufs2_inode->ui_flags); | 679 | ufsi->i_flags = fs32_to_cpu(sb, ufs2_inode->ui_flags); |
@@ -803,12 +803,12 @@ static void ufs2_update_inode(struct inode *inode, struct ufs2_inode *ufs_inode) | |||
803 | ufs_inode->ui_gid = cpu_to_fs32(sb, inode->i_gid); | 803 | ufs_inode->ui_gid = cpu_to_fs32(sb, inode->i_gid); |
804 | 804 | ||
805 | ufs_inode->ui_size = cpu_to_fs64(sb, inode->i_size); | 805 | ufs_inode->ui_size = cpu_to_fs64(sb, inode->i_size); |
806 | ufs_inode->ui_atime.tv_sec = cpu_to_fs32(sb, inode->i_atime.tv_sec); | 806 | ufs_inode->ui_atime = cpu_to_fs64(sb, inode->i_atime.tv_sec); |
807 | ufs_inode->ui_atime.tv_usec = 0; | 807 | ufs_inode->ui_atimensec = cpu_to_fs32(sb, inode->i_atime.tv_nsec); |
808 | ufs_inode->ui_ctime.tv_sec = cpu_to_fs32(sb, inode->i_ctime.tv_sec); | 808 | ufs_inode->ui_ctime = cpu_to_fs64(sb, inode->i_ctime.tv_sec); |
809 | ufs_inode->ui_ctime.tv_usec = 0; | 809 | ufs_inode->ui_ctimensec = cpu_to_fs32(sb, inode->i_ctime.tv_nsec); |
810 | ufs_inode->ui_mtime.tv_sec = cpu_to_fs32(sb, inode->i_mtime.tv_sec); | 810 | ufs_inode->ui_mtime = cpu_to_fs64(sb, inode->i_mtime.tv_sec); |
811 | ufs_inode->ui_mtime.tv_usec = 0; | 811 | ufs_inode->ui_mtimensec = cpu_to_fs32(sb, inode->i_mtime.tv_nsec); |
812 | 812 | ||
813 | ufs_inode->ui_blocks = cpu_to_fs64(sb, inode->i_blocks); | 813 | ufs_inode->ui_blocks = cpu_to_fs64(sb, inode->i_blocks); |
814 | ufs_inode->ui_flags = cpu_to_fs32(sb, ufsi->i_flags); | 814 | ufs_inode->ui_flags = cpu_to_fs32(sb, ufsi->i_flags); |
diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c index 749581fa7729..79c54c85fb58 100644 --- a/fs/ufs/truncate.c +++ b/fs/ufs/truncate.c | |||
@@ -74,7 +74,7 @@ static int ufs_trunc_direct(struct inode *inode) | |||
74 | unsigned i, tmp; | 74 | unsigned i, tmp; |
75 | int retry; | 75 | int retry; |
76 | 76 | ||
77 | UFSD("ENTER\n"); | 77 | UFSD("ENTER: ino %lu\n", inode->i_ino); |
78 | 78 | ||
79 | sb = inode->i_sb; | 79 | sb = inode->i_sb; |
80 | uspi = UFS_SB(sb)->s_uspi; | 80 | uspi = UFS_SB(sb)->s_uspi; |
@@ -96,8 +96,8 @@ static int ufs_trunc_direct(struct inode *inode) | |||
96 | block2 = ufs_fragstoblks (frag3); | 96 | block2 = ufs_fragstoblks (frag3); |
97 | } | 97 | } |
98 | 98 | ||
99 | UFSD("frag1 %llu, frag2 %llu, block1 %llu, block2 %llu, frag3 %llu," | 99 | UFSD("ino %lu, frag1 %llu, frag2 %llu, block1 %llu, block2 %llu," |
100 | " frag4 %llu\n", | 100 | " frag3 %llu, frag4 %llu\n", inode->i_ino, |
101 | (unsigned long long)frag1, (unsigned long long)frag2, | 101 | (unsigned long long)frag1, (unsigned long long)frag2, |
102 | (unsigned long long)block1, (unsigned long long)block2, | 102 | (unsigned long long)block1, (unsigned long long)block2, |
103 | (unsigned long long)frag3, (unsigned long long)frag4); | 103 | (unsigned long long)frag3, (unsigned long long)frag4); |
@@ -163,7 +163,7 @@ next1: | |||
163 | mark_inode_dirty(inode); | 163 | mark_inode_dirty(inode); |
164 | next3: | 164 | next3: |
165 | 165 | ||
166 | UFSD("EXIT\n"); | 166 | UFSD("EXIT: ino %lu\n", inode->i_ino); |
167 | return retry; | 167 | return retry; |
168 | } | 168 | } |
169 | 169 | ||
@@ -248,7 +248,7 @@ static int ufs_trunc_indirect(struct inode *inode, u64 offset, void *p) | |||
248 | } | 248 | } |
249 | ubh_brelse (ind_ubh); | 249 | ubh_brelse (ind_ubh); |
250 | 250 | ||
251 | UFSD("EXIT\n"); | 251 | UFSD("EXIT: ino %lu\n", inode->i_ino); |
252 | 252 | ||
253 | return retry; | 253 | return retry; |
254 | } | 254 | } |
@@ -262,7 +262,7 @@ static int ufs_trunc_dindirect(struct inode *inode, u64 offset, void *p) | |||
262 | void *dind; | 262 | void *dind; |
263 | int retry = 0; | 263 | int retry = 0; |
264 | 264 | ||
265 | UFSD("ENTER\n"); | 265 | UFSD("ENTER: ino %lu\n", inode->i_ino); |
266 | 266 | ||
267 | sb = inode->i_sb; | 267 | sb = inode->i_sb; |
268 | uspi = UFS_SB(sb)->s_uspi; | 268 | uspi = UFS_SB(sb)->s_uspi; |
@@ -312,7 +312,7 @@ static int ufs_trunc_dindirect(struct inode *inode, u64 offset, void *p) | |||
312 | } | 312 | } |
313 | ubh_brelse (dind_bh); | 313 | ubh_brelse (dind_bh); |
314 | 314 | ||
315 | UFSD("EXIT\n"); | 315 | UFSD("EXIT: ino %lu\n", inode->i_ino); |
316 | 316 | ||
317 | return retry; | 317 | return retry; |
318 | } | 318 | } |
@@ -327,7 +327,7 @@ static int ufs_trunc_tindirect(struct inode *inode) | |||
327 | void *tind, *p; | 327 | void *tind, *p; |
328 | int retry; | 328 | int retry; |
329 | 329 | ||
330 | UFSD("ENTER\n"); | 330 | UFSD("ENTER: ino %lu\n", inode->i_ino); |
331 | 331 | ||
332 | retry = 0; | 332 | retry = 0; |
333 | 333 | ||
@@ -348,7 +348,7 @@ static int ufs_trunc_tindirect(struct inode *inode) | |||
348 | } | 348 | } |
349 | 349 | ||
350 | for (i = tindirect_block ; i < uspi->s_apb ; i++) { | 350 | for (i = tindirect_block ; i < uspi->s_apb ; i++) { |
351 | tind = ubh_get_addr32 (tind_bh, i); | 351 | tind = ubh_get_data_ptr(uspi, tind_bh, i); |
352 | retry |= ufs_trunc_dindirect(inode, UFS_NDADDR + | 352 | retry |= ufs_trunc_dindirect(inode, UFS_NDADDR + |
353 | uspi->s_apb + ((i + 1) << uspi->s_2apbshift), tind); | 353 | uspi->s_apb + ((i + 1) << uspi->s_2apbshift), tind); |
354 | ubh_mark_buffer_dirty(tind_bh); | 354 | ubh_mark_buffer_dirty(tind_bh); |
@@ -372,19 +372,21 @@ static int ufs_trunc_tindirect(struct inode *inode) | |||
372 | } | 372 | } |
373 | ubh_brelse (tind_bh); | 373 | ubh_brelse (tind_bh); |
374 | 374 | ||
375 | UFSD("EXIT\n"); | 375 | UFSD("EXIT: ino %lu\n", inode->i_ino); |
376 | return retry; | 376 | return retry; |
377 | } | 377 | } |
378 | 378 | ||
379 | static int ufs_alloc_lastblock(struct inode *inode) | 379 | static int ufs_alloc_lastblock(struct inode *inode) |
380 | { | 380 | { |
381 | int err = 0; | 381 | int err = 0; |
382 | struct super_block *sb = inode->i_sb; | ||
382 | struct address_space *mapping = inode->i_mapping; | 383 | struct address_space *mapping = inode->i_mapping; |
383 | struct ufs_sb_private_info *uspi = UFS_SB(inode->i_sb)->s_uspi; | 384 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; |
384 | unsigned i, end; | 385 | unsigned i, end; |
385 | sector_t lastfrag; | 386 | sector_t lastfrag; |
386 | struct page *lastpage; | 387 | struct page *lastpage; |
387 | struct buffer_head *bh; | 388 | struct buffer_head *bh; |
389 | u64 phys64; | ||
388 | 390 | ||
389 | lastfrag = (i_size_read(inode) + uspi->s_fsize - 1) >> uspi->s_fshift; | 391 | lastfrag = (i_size_read(inode) + uspi->s_fsize - 1) >> uspi->s_fshift; |
390 | 392 | ||
@@ -424,6 +426,20 @@ static int ufs_alloc_lastblock(struct inode *inode) | |||
424 | set_page_dirty(lastpage); | 426 | set_page_dirty(lastpage); |
425 | } | 427 | } |
426 | 428 | ||
429 | if (lastfrag >= UFS_IND_FRAGMENT) { | ||
430 | end = uspi->s_fpb - ufs_fragnum(lastfrag) - 1; | ||
431 | phys64 = bh->b_blocknr + 1; | ||
432 | for (i = 0; i < end; ++i) { | ||
433 | bh = sb_getblk(sb, i + phys64); | ||
434 | lock_buffer(bh); | ||
435 | memset(bh->b_data, 0, sb->s_blocksize); | ||
436 | set_buffer_uptodate(bh); | ||
437 | mark_buffer_dirty(bh); | ||
438 | unlock_buffer(bh); | ||
439 | sync_dirty_buffer(bh); | ||
440 | brelse(bh); | ||
441 | } | ||
442 | } | ||
427 | out_unlock: | 443 | out_unlock: |
428 | ufs_put_locked_page(lastpage); | 444 | ufs_put_locked_page(lastpage); |
429 | out: | 445 | out: |
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index e2bea6a661f0..69e9e80735d2 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
@@ -1829,11 +1829,11 @@ xfs_buf_init(void) | |||
1829 | if (!xfs_buf_zone) | 1829 | if (!xfs_buf_zone) |
1830 | goto out_free_trace_buf; | 1830 | goto out_free_trace_buf; |
1831 | 1831 | ||
1832 | xfslogd_workqueue = create_freezeable_workqueue("xfslogd"); | 1832 | xfslogd_workqueue = create_workqueue("xfslogd"); |
1833 | if (!xfslogd_workqueue) | 1833 | if (!xfslogd_workqueue) |
1834 | goto out_free_buf_zone; | 1834 | goto out_free_buf_zone; |
1835 | 1835 | ||
1836 | xfsdatad_workqueue = create_freezeable_workqueue("xfsdatad"); | 1836 | xfsdatad_workqueue = create_workqueue("xfsdatad"); |
1837 | if (!xfsdatad_workqueue) | 1837 | if (!xfsdatad_workqueue) |
1838 | goto out_destroy_xfslogd_workqueue; | 1838 | goto out_destroy_xfslogd_workqueue; |
1839 | 1839 | ||