diff options
Diffstat (limited to 'fs')
90 files changed, 487 insertions, 594 deletions
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c index 6fcb1e7095cf..92828281a30b 100644 --- a/fs/9p/vfs_addr.c +++ b/fs/9p/vfs_addr.c | |||
| @@ -57,7 +57,7 @@ static int v9fs_vfs_readpage(struct file *filp, struct page *page) | |||
| 57 | buffer = kmap(page); | 57 | buffer = kmap(page); |
| 58 | offset = page_offset(page); | 58 | offset = page_offset(page); |
| 59 | 59 | ||
| 60 | retval = v9fs_file_readn(filp, buffer, NULL, offset, PAGE_CACHE_SIZE); | 60 | retval = v9fs_file_readn(filp, buffer, NULL, PAGE_CACHE_SIZE, offset); |
| 61 | if (retval < 0) | 61 | if (retval < 0) |
| 62 | goto done; | 62 | goto done; |
| 63 | 63 | ||
diff --git a/fs/Kconfig b/fs/Kconfig index a97263be6a91..0e7da7bb5d93 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
| @@ -186,32 +186,7 @@ source "fs/romfs/Kconfig" | |||
| 186 | source "fs/sysv/Kconfig" | 186 | source "fs/sysv/Kconfig" |
| 187 | source "fs/ufs/Kconfig" | 187 | source "fs/ufs/Kconfig" |
| 188 | source "fs/exofs/Kconfig" | 188 | source "fs/exofs/Kconfig" |
| 189 | 189 | source "fs/nilfs2/Kconfig" | |
| 190 | config NILFS2_FS | ||
| 191 | tristate "NILFS2 file system support (EXPERIMENTAL)" | ||
| 192 | depends on BLOCK && EXPERIMENTAL | ||
| 193 | select CRC32 | ||
| 194 | help | ||
| 195 | NILFS2 is a log-structured file system (LFS) supporting continuous | ||
| 196 | snapshotting. In addition to versioning capability of the entire | ||
| 197 | file system, users can even restore files mistakenly overwritten or | ||
| 198 | destroyed just a few seconds ago. Since this file system can keep | ||
| 199 | consistency like conventional LFS, it achieves quick recovery after | ||
| 200 | system crashes. | ||
| 201 | |||
| 202 | NILFS2 creates a number of checkpoints every few seconds or per | ||
| 203 | synchronous write basis (unless there is no change). Users can | ||
| 204 | select significant versions among continuously created checkpoints, | ||
| 205 | and can change them into snapshots which will be preserved for long | ||
| 206 | periods until they are changed back to checkpoints. Each | ||
| 207 | snapshot is mountable as a read-only file system concurrently with | ||
| 208 | its writable mount, and this feature is convenient for online backup. | ||
| 209 | |||
| 210 | Some features including atime, extended attributes, and POSIX ACLs, | ||
| 211 | are not supported yet. | ||
| 212 | |||
| 213 | To compile this file system support as a module, choose M here: the | ||
| 214 | module will be called nilfs2. If unsure, say N. | ||
| 215 | 190 | ||
| 216 | endif # MISC_FILESYSTEMS | 191 | endif # MISC_FILESYSTEMS |
| 217 | 192 | ||
diff --git a/fs/adfs/super.c b/fs/adfs/super.c index aad92f0a1048..6910a98bd73c 100644 --- a/fs/adfs/super.c +++ b/fs/adfs/super.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/parser.h> | 13 | #include <linux/parser.h> |
| 14 | #include <linux/mount.h> | 14 | #include <linux/mount.h> |
| 15 | #include <linux/seq_file.h> | 15 | #include <linux/seq_file.h> |
| 16 | #include <linux/smp_lock.h> | ||
| 16 | #include <linux/statfs.h> | 17 | #include <linux/statfs.h> |
| 17 | #include "adfs.h" | 18 | #include "adfs.h" |
| 18 | #include "dir_f.h" | 19 | #include "dir_f.h" |
diff --git a/fs/afs/dir.c b/fs/afs/dir.c index 9bd757774c9e..88067f36e5e7 100644 --- a/fs/afs/dir.c +++ b/fs/afs/dir.c | |||
| @@ -564,7 +564,7 @@ static struct dentry *afs_lookup(struct inode *dir, struct dentry *dentry, | |||
| 564 | static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd) | 564 | static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd) |
| 565 | { | 565 | { |
| 566 | struct afs_vnode *vnode, *dir; | 566 | struct afs_vnode *vnode, *dir; |
| 567 | struct afs_fid fid; | 567 | struct afs_fid uninitialized_var(fid); |
| 568 | struct dentry *parent; | 568 | struct dentry *parent; |
| 569 | struct key *key; | 569 | struct key *key; |
| 570 | void *dir_version; | 570 | void *dir_version; |
diff --git a/fs/afs/super.c b/fs/afs/super.c index ad0514d0115f..e1ea1c240b6a 100644 --- a/fs/afs/super.c +++ b/fs/afs/super.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
| 19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
| 20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
| 21 | #include <linux/smp_lock.h> | ||
| 21 | #include <linux/fs.h> | 22 | #include <linux/fs.h> |
| 22 | #include <linux/pagemap.h> | 23 | #include <linux/pagemap.h> |
| 23 | #include <linux/parser.h> | 24 | #include <linux/parser.h> |
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c index f3da2eb51f56..00bf8fcb245f 100644 --- a/fs/autofs4/dev-ioctl.c +++ b/fs/autofs4/dev-ioctl.c | |||
| @@ -19,7 +19,6 @@ | |||
| 19 | #include <linux/sched.h> | 19 | #include <linux/sched.h> |
| 20 | #include <linux/compat.h> | 20 | #include <linux/compat.h> |
| 21 | #include <linux/syscalls.h> | 21 | #include <linux/syscalls.h> |
| 22 | #include <linux/smp_lock.h> | ||
| 23 | #include <linux/magic.h> | 22 | #include <linux/magic.h> |
| 24 | #include <linux/dcache.h> | 23 | #include <linux/dcache.h> |
| 25 | #include <linux/uaccess.h> | 24 | #include <linux/uaccess.h> |
diff --git a/fs/bfs/dir.c b/fs/bfs/dir.c index 54bd07d44e68..1e41aadb1068 100644 --- a/fs/bfs/dir.c +++ b/fs/bfs/dir.c | |||
| @@ -8,7 +8,6 @@ | |||
| 8 | #include <linux/time.h> | 8 | #include <linux/time.h> |
| 9 | #include <linux/string.h> | 9 | #include <linux/string.h> |
| 10 | #include <linux/fs.h> | 10 | #include <linux/fs.h> |
| 11 | #include <linux/smp_lock.h> | ||
| 12 | #include <linux/buffer_head.h> | 11 | #include <linux/buffer_head.h> |
| 13 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
| 14 | #include "bfs.h" | 13 | #include "bfs.h" |
diff --git a/fs/bfs/file.c b/fs/bfs/file.c index 6a021265f018..88b9a3ff44e4 100644 --- a/fs/bfs/file.c +++ b/fs/bfs/file.c | |||
| @@ -11,7 +11,6 @@ | |||
| 11 | 11 | ||
| 12 | #include <linux/fs.h> | 12 | #include <linux/fs.h> |
| 13 | #include <linux/buffer_head.h> | 13 | #include <linux/buffer_head.h> |
| 14 | #include <linux/smp_lock.h> | ||
| 15 | #include "bfs.h" | 14 | #include "bfs.h" |
| 16 | 15 | ||
| 17 | #undef DEBUG | 16 | #undef DEBUG |
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index de1e2fd32080..9d8ba4d54a37 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | #include <linux/time.h> | 26 | #include <linux/time.h> |
| 27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
| 28 | #include <linux/string.h> | 28 | #include <linux/string.h> |
| 29 | #include <linux/smp_lock.h> | ||
| 30 | #include <linux/backing-dev.h> | 29 | #include <linux/backing-dev.h> |
| 31 | #include <linux/mpage.h> | 30 | #include <linux/mpage.h> |
| 32 | #include <linux/swap.h> | 31 | #include <linux/swap.h> |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 7c3cd248d8d6..4b833972273a 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
| @@ -22,7 +22,6 @@ | |||
| 22 | #include <linux/time.h> | 22 | #include <linux/time.h> |
| 23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
| 24 | #include <linux/string.h> | 24 | #include <linux/string.h> |
| 25 | #include <linux/smp_lock.h> | ||
| 26 | #include <linux/backing-dev.h> | 25 | #include <linux/backing-dev.h> |
| 27 | #include <linux/mpage.h> | 26 | #include <linux/mpage.h> |
| 28 | #include <linux/swap.h> | 27 | #include <linux/swap.h> |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 7ffa3d34ea19..791eab19e330 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | #include <linux/time.h> | 26 | #include <linux/time.h> |
| 27 | #include <linux/init.h> | 27 | #include <linux/init.h> |
| 28 | #include <linux/string.h> | 28 | #include <linux/string.h> |
| 29 | #include <linux/smp_lock.h> | ||
| 30 | #include <linux/backing-dev.h> | 29 | #include <linux/backing-dev.h> |
| 31 | #include <linux/mpage.h> | 30 | #include <linux/mpage.h> |
| 32 | #include <linux/swap.h> | 31 | #include <linux/swap.h> |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 9f4db848db10..bd88f25889f7 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
| @@ -27,7 +27,6 @@ | |||
| 27 | #include <linux/time.h> | 27 | #include <linux/time.h> |
| 28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
| 29 | #include <linux/string.h> | 29 | #include <linux/string.h> |
| 30 | #include <linux/smp_lock.h> | ||
| 31 | #include <linux/backing-dev.h> | 30 | #include <linux/backing-dev.h> |
| 32 | #include <linux/mount.h> | 31 | #include <linux/mount.h> |
| 33 | #include <linux/mpage.h> | 32 | #include <linux/mpage.h> |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 9f179d4832d5..6d6d06cb6dfc 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
| 27 | #include <linux/seq_file.h> | 27 | #include <linux/seq_file.h> |
| 28 | #include <linux/string.h> | 28 | #include <linux/string.h> |
| 29 | #include <linux/smp_lock.h> | ||
| 30 | #include <linux/backing-dev.h> | 29 | #include <linux/backing-dev.h> |
| 31 | #include <linux/mount.h> | 30 | #include <linux/mount.h> |
| 32 | #include <linux/mpage.h> | 31 | #include <linux/mpage.h> |
diff --git a/fs/char_dev.c b/fs/char_dev.c index b7c9d5187a75..a173551e19d7 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c | |||
| @@ -13,7 +13,6 @@ | |||
| 13 | #include <linux/major.h> | 13 | #include <linux/major.h> |
| 14 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
| 15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 16 | #include <linux/smp_lock.h> | ||
| 17 | #include <linux/seq_file.h> | 16 | #include <linux/seq_file.h> |
| 18 | 17 | ||
| 19 | #include <linux/kobject.h> | 18 | #include <linux/kobject.h> |
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index 7f19fefd3d45..42cec2a7c0cf 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c | |||
| @@ -261,6 +261,8 @@ static ssize_t cifs_stats_proc_write(struct file *file, | |||
| 261 | atomic_set(&tcon->num_reads, 0); | 261 | atomic_set(&tcon->num_reads, 0); |
| 262 | atomic_set(&tcon->num_oplock_brks, 0); | 262 | atomic_set(&tcon->num_oplock_brks, 0); |
| 263 | atomic_set(&tcon->num_opens, 0); | 263 | atomic_set(&tcon->num_opens, 0); |
| 264 | atomic_set(&tcon->num_posixopens, 0); | ||
| 265 | atomic_set(&tcon->num_posixmkdirs, 0); | ||
| 264 | atomic_set(&tcon->num_closes, 0); | 266 | atomic_set(&tcon->num_closes, 0); |
| 265 | atomic_set(&tcon->num_deletes, 0); | 267 | atomic_set(&tcon->num_deletes, 0); |
| 266 | atomic_set(&tcon->num_mkdirs, 0); | 268 | atomic_set(&tcon->num_mkdirs, 0); |
| @@ -347,11 +349,15 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v) | |||
| 347 | atomic_read(&tcon->num_locks), | 349 | atomic_read(&tcon->num_locks), |
| 348 | atomic_read(&tcon->num_hardlinks), | 350 | atomic_read(&tcon->num_hardlinks), |
| 349 | atomic_read(&tcon->num_symlinks)); | 351 | atomic_read(&tcon->num_symlinks)); |
| 350 | seq_printf(m, "\nOpens: %d Closes: %d" | 352 | seq_printf(m, "\nOpens: %d Closes: %d " |
| 351 | "Deletes: %d", | 353 | "Deletes: %d", |
| 352 | atomic_read(&tcon->num_opens), | 354 | atomic_read(&tcon->num_opens), |
| 353 | atomic_read(&tcon->num_closes), | 355 | atomic_read(&tcon->num_closes), |
| 354 | atomic_read(&tcon->num_deletes)); | 356 | atomic_read(&tcon->num_deletes)); |
| 357 | seq_printf(m, "\nPosix Opens: %d " | ||
| 358 | "Posix Mkdirs: %d", | ||
| 359 | atomic_read(&tcon->num_posixopens), | ||
| 360 | atomic_read(&tcon->num_posixmkdirs)); | ||
| 355 | seq_printf(m, "\nMkdirs: %d Rmdirs: %d", | 361 | seq_printf(m, "\nMkdirs: %d Rmdirs: %d", |
| 356 | atomic_read(&tcon->num_mkdirs), | 362 | atomic_read(&tcon->num_mkdirs), |
| 357 | atomic_read(&tcon->num_rmdirs)); | 363 | atomic_read(&tcon->num_rmdirs)); |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 63f6cdfa5638..6084d6379c03 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
| @@ -260,6 +260,8 @@ struct cifsTconInfo { | |||
| 260 | atomic_t num_closes; | 260 | atomic_t num_closes; |
| 261 | atomic_t num_deletes; | 261 | atomic_t num_deletes; |
| 262 | atomic_t num_mkdirs; | 262 | atomic_t num_mkdirs; |
| 263 | atomic_t num_posixopens; | ||
| 264 | atomic_t num_posixmkdirs; | ||
| 263 | atomic_t num_rmdirs; | 265 | atomic_t num_rmdirs; |
| 264 | atomic_t num_renames; | 266 | atomic_t num_renames; |
| 265 | atomic_t num_t2renames; | 267 | atomic_t num_t2renames; |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 922f5fe2084c..1866bc2927d4 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
| @@ -1113,7 +1113,10 @@ PsxCreat: | |||
| 1113 | psx_create_err: | 1113 | psx_create_err: |
| 1114 | cifs_buf_release(pSMB); | 1114 | cifs_buf_release(pSMB); |
| 1115 | 1115 | ||
| 1116 | cifs_stats_inc(&tcon->num_mkdirs); | 1116 | if (posix_flags & SMB_O_DIRECTORY) |
| 1117 | cifs_stats_inc(&tcon->num_posixmkdirs); | ||
| 1118 | else | ||
| 1119 | cifs_stats_inc(&tcon->num_posixopens); | ||
| 1117 | 1120 | ||
| 1118 | if (rc == -EAGAIN) | 1121 | if (rc == -EAGAIN) |
| 1119 | goto PsxCreat; | 1122 | goto PsxCreat; |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index e16d7592116a..9bb5c8750736 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
| @@ -2726,6 +2726,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, | |||
| 2726 | strncpy(tcon->treeName, tree, MAX_TREE_SIZE); | 2726 | strncpy(tcon->treeName, tree, MAX_TREE_SIZE); |
| 2727 | 2727 | ||
| 2728 | /* mostly informational -- no need to fail on error here */ | 2728 | /* mostly informational -- no need to fail on error here */ |
| 2729 | kfree(tcon->nativeFileSystem); | ||
| 2729 | tcon->nativeFileSystem = cifs_strndup_from_ucs(bcc_ptr, | 2730 | tcon->nativeFileSystem = cifs_strndup_from_ucs(bcc_ptr, |
| 2730 | bytes_left, is_unicode, | 2731 | bytes_left, is_unicode, |
| 2731 | nls_codepage); | 2732 | nls_codepage); |
diff --git a/fs/compat.c b/fs/compat.c index fbadb947727b..94502dab972a 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
| @@ -32,7 +32,6 @@ | |||
| 32 | #include <linux/smb_mount.h> | 32 | #include <linux/smb_mount.h> |
| 33 | #include <linux/ncp_mount.h> | 33 | #include <linux/ncp_mount.h> |
| 34 | #include <linux/nfs4_mount.h> | 34 | #include <linux/nfs4_mount.h> |
| 35 | #include <linux/smp_lock.h> | ||
| 36 | #include <linux/syscalls.h> | 35 | #include <linux/syscalls.h> |
| 37 | #include <linux/ctype.h> | 36 | #include <linux/ctype.h> |
| 38 | #include <linux/module.h> | 37 | #include <linux/module.h> |
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c index 626c7483b4de..f28f070a60fc 100644 --- a/fs/compat_ioctl.c +++ b/fs/compat_ioctl.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/compiler.h> | 19 | #include <linux/compiler.h> |
| 20 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
| 21 | #include <linux/smp.h> | 21 | #include <linux/smp.h> |
| 22 | #include <linux/smp_lock.h> | ||
| 22 | #include <linux/ioctl.h> | 23 | #include <linux/ioctl.h> |
| 23 | #include <linux/if.h> | 24 | #include <linux/if.h> |
| 24 | #include <linux/if_bridge.h> | 25 | #include <linux/if_bridge.h> |
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c index 205ec95b347e..eb507c453c5f 100644 --- a/fs/dlm/lock.c +++ b/fs/dlm/lock.c | |||
| @@ -435,7 +435,7 @@ static int search_rsb(struct dlm_ls *ls, char *name, int len, int b, | |||
| 435 | static int find_rsb(struct dlm_ls *ls, char *name, int namelen, | 435 | static int find_rsb(struct dlm_ls *ls, char *name, int namelen, |
| 436 | unsigned int flags, struct dlm_rsb **r_ret) | 436 | unsigned int flags, struct dlm_rsb **r_ret) |
| 437 | { | 437 | { |
| 438 | struct dlm_rsb *r, *tmp; | 438 | struct dlm_rsb *r = NULL, *tmp; |
| 439 | uint32_t hash, bucket; | 439 | uint32_t hash, bucket; |
| 440 | int error = -EINVAL; | 440 | int error = -EINVAL; |
| 441 | 441 | ||
diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index cdb580a9c7a2..618a60f03886 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c | |||
| @@ -902,7 +902,7 @@ static void tcp_connect_to_sock(struct connection *con) | |||
| 902 | int result = -EHOSTUNREACH; | 902 | int result = -EHOSTUNREACH; |
| 903 | struct sockaddr_storage saddr, src_addr; | 903 | struct sockaddr_storage saddr, src_addr; |
| 904 | int addr_len; | 904 | int addr_len; |
| 905 | struct socket *sock; | 905 | struct socket *sock = NULL; |
| 906 | 906 | ||
| 907 | if (con->nodeid == 0) { | 907 | if (con->nodeid == 0) { |
| 908 | log_print("attempt to connect sock 0 foiled"); | 908 | log_print("attempt to connect sock 0 foiled"); |
| @@ -962,6 +962,8 @@ out_err: | |||
| 962 | if (con->sock) { | 962 | if (con->sock) { |
| 963 | sock_release(con->sock); | 963 | sock_release(con->sock); |
| 964 | con->sock = NULL; | 964 | con->sock = NULL; |
| 965 | } else if (sock) { | ||
| 966 | sock_release(sock); | ||
| 965 | } | 967 | } |
| 966 | /* | 968 | /* |
| 967 | * Some errors are fatal and this list might need adjusting. For other | 969 | * Some errors are fatal and this list might need adjusting. For other |
diff --git a/fs/dlm/plock.c b/fs/dlm/plock.c index 894a32d438d5..16f682e26c07 100644 --- a/fs/dlm/plock.c +++ b/fs/dlm/plock.c | |||
| @@ -353,7 +353,7 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count, | |||
| 353 | { | 353 | { |
| 354 | struct dlm_plock_info info; | 354 | struct dlm_plock_info info; |
| 355 | struct plock_op *op; | 355 | struct plock_op *op; |
| 356 | int found = 0; | 356 | int found = 0, do_callback = 0; |
| 357 | 357 | ||
| 358 | if (count != sizeof(info)) | 358 | if (count != sizeof(info)) |
| 359 | return -EINVAL; | 359 | return -EINVAL; |
| @@ -366,21 +366,24 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count, | |||
| 366 | 366 | ||
| 367 | spin_lock(&ops_lock); | 367 | spin_lock(&ops_lock); |
| 368 | list_for_each_entry(op, &recv_list, list) { | 368 | list_for_each_entry(op, &recv_list, list) { |
| 369 | if (op->info.fsid == info.fsid && op->info.number == info.number && | 369 | if (op->info.fsid == info.fsid && |
| 370 | op->info.number == info.number && | ||
| 370 | op->info.owner == info.owner) { | 371 | op->info.owner == info.owner) { |
| 372 | struct plock_xop *xop = (struct plock_xop *)op; | ||
| 371 | list_del_init(&op->list); | 373 | list_del_init(&op->list); |
| 372 | found = 1; | ||
| 373 | op->done = 1; | ||
| 374 | memcpy(&op->info, &info, sizeof(info)); | 374 | memcpy(&op->info, &info, sizeof(info)); |
| 375 | if (xop->callback) | ||
| 376 | do_callback = 1; | ||
| 377 | else | ||
| 378 | op->done = 1; | ||
| 379 | found = 1; | ||
| 375 | break; | 380 | break; |
| 376 | } | 381 | } |
| 377 | } | 382 | } |
| 378 | spin_unlock(&ops_lock); | 383 | spin_unlock(&ops_lock); |
| 379 | 384 | ||
| 380 | if (found) { | 385 | if (found) { |
| 381 | struct plock_xop *xop; | 386 | if (do_callback) |
| 382 | xop = (struct plock_xop *)op; | ||
| 383 | if (xop->callback) | ||
| 384 | dlm_plock_callback(op); | 387 | dlm_plock_callback(op); |
| 385 | else | 388 | else |
| 386 | wake_up(&recv_wq); | 389 | wake_up(&recv_wq); |
diff --git a/fs/exofs/common.h b/fs/exofs/common.h index 24667eedc023..c6718e4817fe 100644 --- a/fs/exofs/common.h +++ b/fs/exofs/common.h | |||
| @@ -2,9 +2,7 @@ | |||
| 2 | * common.h - Common definitions for both Kernel and user-mode utilities | 2 | * common.h - Common definitions for both Kernel and user-mode utilities |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2005, 2006 | 4 | * Copyright (C) 2005, 2006 |
| 5 | * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com) | 5 | * Avishay Traeger (avishay@gmail.com) |
| 6 | * Copyright (C) 2005, 2006 | ||
| 7 | * International Business Machines | ||
| 8 | * Copyright (C) 2008, 2009 | 6 | * Copyright (C) 2008, 2009 |
| 9 | * Boaz Harrosh <bharrosh@panasas.com> | 7 | * Boaz Harrosh <bharrosh@panasas.com> |
| 10 | * | 8 | * |
diff --git a/fs/exofs/dir.c b/fs/exofs/dir.c index 65b0c8c776a1..4cfab1cc75c0 100644 --- a/fs/exofs/dir.c +++ b/fs/exofs/dir.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2005, 2006 | 2 | * Copyright (C) 2005, 2006 |
| 3 | * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com) | 3 | * Avishay Traeger (avishay@gmail.com) |
| 4 | * Copyright (C) 2005, 2006 | ||
| 5 | * International Business Machines | ||
| 6 | * Copyright (C) 2008, 2009 | 4 | * Copyright (C) 2008, 2009 |
| 7 | * Boaz Harrosh <bharrosh@panasas.com> | 5 | * Boaz Harrosh <bharrosh@panasas.com> |
| 8 | * | 6 | * |
diff --git a/fs/exofs/exofs.h b/fs/exofs/exofs.h index 0fd4c7859679..5ec72e020b22 100644 --- a/fs/exofs/exofs.h +++ b/fs/exofs/exofs.h | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2005, 2006 | 2 | * Copyright (C) 2005, 2006 |
| 3 | * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com) | 3 | * Avishay Traeger (avishay@gmail.com) |
| 4 | * Copyright (C) 2005, 2006 | ||
| 5 | * International Business Machines | ||
| 6 | * Copyright (C) 2008, 2009 | 4 | * Copyright (C) 2008, 2009 |
| 7 | * Boaz Harrosh <bharrosh@panasas.com> | 5 | * Boaz Harrosh <bharrosh@panasas.com> |
| 8 | * | 6 | * |
| @@ -156,6 +154,9 @@ ino_t exofs_parent_ino(struct dentry *child); | |||
| 156 | int exofs_set_link(struct inode *, struct exofs_dir_entry *, struct page *, | 154 | int exofs_set_link(struct inode *, struct exofs_dir_entry *, struct page *, |
| 157 | struct inode *); | 155 | struct inode *); |
| 158 | 156 | ||
| 157 | /* super.c */ | ||
| 158 | int exofs_sync_fs(struct super_block *sb, int wait); | ||
| 159 | |||
| 159 | /********************* | 160 | /********************* |
| 160 | * operation vectors * | 161 | * operation vectors * |
| 161 | *********************/ | 162 | *********************/ |
diff --git a/fs/exofs/file.c b/fs/exofs/file.c index 6ed7fe484752..839b9dc1e70f 100644 --- a/fs/exofs/file.c +++ b/fs/exofs/file.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2005, 2006 | 2 | * Copyright (C) 2005, 2006 |
| 3 | * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com) | 3 | * Avishay Traeger (avishay@gmail.com) |
| 4 | * Copyright (C) 2005, 2006 | ||
| 5 | * International Business Machines | ||
| 6 | * Copyright (C) 2008, 2009 | 4 | * Copyright (C) 2008, 2009 |
| 7 | * Boaz Harrosh <bharrosh@panasas.com> | 5 | * Boaz Harrosh <bharrosh@panasas.com> |
| 8 | * | 6 | * |
| @@ -47,16 +45,23 @@ static int exofs_file_fsync(struct file *filp, struct dentry *dentry, | |||
| 47 | { | 45 | { |
| 48 | int ret; | 46 | int ret; |
| 49 | struct address_space *mapping = filp->f_mapping; | 47 | struct address_space *mapping = filp->f_mapping; |
| 48 | struct inode *inode = dentry->d_inode; | ||
| 49 | struct super_block *sb; | ||
| 50 | 50 | ||
| 51 | ret = filemap_write_and_wait(mapping); | 51 | ret = filemap_write_and_wait(mapping); |
| 52 | if (ret) | 52 | if (ret) |
| 53 | return ret; | 53 | return ret; |
| 54 | 54 | ||
| 55 | /*Note: file_fsync below also calles sync_blockdev, which is a no-op | 55 | /* sync the inode attributes */ |
| 56 | * for exofs, but other then that it does sync_inode and | 56 | ret = write_inode_now(inode, 1); |
| 57 | * sync_superblock which is what we need here. | 57 | |
| 58 | */ | 58 | /* This is a good place to write the sb */ |
| 59 | return file_fsync(filp, dentry, datasync); | 59 | /* TODO: Sechedule an sb-sync on create */ |
| 60 | sb = inode->i_sb; | ||
| 61 | if (sb->s_dirt) | ||
| 62 | exofs_sync_fs(sb, 1); | ||
| 63 | |||
| 64 | return ret; | ||
| 60 | } | 65 | } |
| 61 | 66 | ||
| 62 | static int exofs_flush(struct file *file, fl_owner_t id) | 67 | static int exofs_flush(struct file *file, fl_owner_t id) |
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index 77d0a295eb1c..6c10f7476699 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2005, 2006 | 2 | * Copyright (C) 2005, 2006 |
| 3 | * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com) | 3 | * Avishay Traeger (avishay@gmail.com) |
| 4 | * Copyright (C) 2005, 2006 | ||
| 5 | * International Business Machines | ||
| 6 | * Copyright (C) 2008, 2009 | 4 | * Copyright (C) 2008, 2009 |
| 7 | * Boaz Harrosh <bharrosh@panasas.com> | 5 | * Boaz Harrosh <bharrosh@panasas.com> |
| 8 | * | 6 | * |
| @@ -295,6 +293,9 @@ static int read_exec(struct page_collect *pcol, bool is_sync) | |||
| 295 | err: | 293 | err: |
| 296 | if (!is_sync) | 294 | if (!is_sync) |
| 297 | _unlock_pcol_pages(pcol, ret, READ); | 295 | _unlock_pcol_pages(pcol, ret, READ); |
| 296 | else /* Pages unlocked by caller in sync mode only free bio */ | ||
| 297 | pcol_free(pcol); | ||
| 298 | |||
| 298 | kfree(pcol_copy); | 299 | kfree(pcol_copy); |
| 299 | if (or) | 300 | if (or) |
| 300 | osd_end_request(or); | 301 | osd_end_request(or); |
diff --git a/fs/exofs/namei.c b/fs/exofs/namei.c index 77fdd765e76d..b7dd0c236863 100644 --- a/fs/exofs/namei.c +++ b/fs/exofs/namei.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2005, 2006 | 2 | * Copyright (C) 2005, 2006 |
| 3 | * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com) | 3 | * Avishay Traeger (avishay@gmail.com) |
| 4 | * Copyright (C) 2005, 2006 | ||
| 5 | * International Business Machines | ||
| 6 | * Copyright (C) 2008, 2009 | 4 | * Copyright (C) 2008, 2009 |
| 7 | * Boaz Harrosh <bharrosh@panasas.com> | 5 | * Boaz Harrosh <bharrosh@panasas.com> |
| 8 | * | 6 | * |
diff --git a/fs/exofs/osd.c b/fs/exofs/osd.c index b3d2ccb87aaa..4372542df284 100644 --- a/fs/exofs/osd.c +++ b/fs/exofs/osd.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2005, 2006 | 2 | * Copyright (C) 2005, 2006 |
| 3 | * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com) | 3 | * Avishay Traeger (avishay@gmail.com) |
| 4 | * Copyright (C) 2005, 2006 | ||
| 5 | * International Business Machines | ||
| 6 | * Copyright (C) 2008, 2009 | 4 | * Copyright (C) 2008, 2009 |
| 7 | * Boaz Harrosh <bharrosh@panasas.com> | 5 | * Boaz Harrosh <bharrosh@panasas.com> |
| 8 | * | 6 | * |
diff --git a/fs/exofs/super.c b/fs/exofs/super.c index 8216c5b77b53..5ab10c3bbebe 100644 --- a/fs/exofs/super.c +++ b/fs/exofs/super.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2005, 2006 | 2 | * Copyright (C) 2005, 2006 |
| 3 | * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com) | 3 | * Avishay Traeger (avishay@gmail.com) |
| 4 | * Copyright (C) 2005, 2006 | ||
| 5 | * International Business Machines | ||
| 6 | * Copyright (C) 2008, 2009 | 4 | * Copyright (C) 2008, 2009 |
| 7 | * Boaz Harrosh <bharrosh@panasas.com> | 5 | * Boaz Harrosh <bharrosh@panasas.com> |
| 8 | * | 6 | * |
| @@ -33,6 +31,7 @@ | |||
| 33 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 31 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| 34 | */ | 32 | */ |
| 35 | 33 | ||
| 34 | #include <linux/smp_lock.h> | ||
| 36 | #include <linux/string.h> | 35 | #include <linux/string.h> |
| 37 | #include <linux/parser.h> | 36 | #include <linux/parser.h> |
| 38 | #include <linux/vfs.h> | 37 | #include <linux/vfs.h> |
| @@ -200,7 +199,7 @@ static const struct export_operations exofs_export_ops; | |||
| 200 | /* | 199 | /* |
| 201 | * Write the superblock to the OSD | 200 | * Write the superblock to the OSD |
| 202 | */ | 201 | */ |
| 203 | static int exofs_sync_fs(struct super_block *sb, int wait) | 202 | int exofs_sync_fs(struct super_block *sb, int wait) |
| 204 | { | 203 | { |
| 205 | struct exofs_sb_info *sbi; | 204 | struct exofs_sb_info *sbi; |
| 206 | struct exofs_fscb *fscb; | 205 | struct exofs_fscb *fscb; |
diff --git a/fs/exofs/symlink.c b/fs/exofs/symlink.c index 36e2d7bc7f7b..4dd687c3e747 100644 --- a/fs/exofs/symlink.c +++ b/fs/exofs/symlink.c | |||
| @@ -1,8 +1,6 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright (C) 2005, 2006 | 2 | * Copyright (C) 2005, 2006 |
| 3 | * Avishay Traeger (avishay@gmail.com) (avishay@il.ibm.com) | 3 | * Avishay Traeger (avishay@gmail.com) |
| 4 | * Copyright (C) 2005, 2006 | ||
| 5 | * International Business Machines | ||
| 6 | * Copyright (C) 2008, 2009 | 4 | * Copyright (C) 2008, 2009 |
| 7 | * Boaz Harrosh <bharrosh@panasas.com> | 5 | * Boaz Harrosh <bharrosh@panasas.com> |
| 8 | * | 6 | * |
diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c index 7cb4badef927..e7431309bdca 100644 --- a/fs/ext2/ioctl.c +++ b/fs/ext2/ioctl.c | |||
| @@ -13,7 +13,6 @@ | |||
| 13 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
| 14 | #include <linux/compat.h> | 14 | #include <linux/compat.h> |
| 15 | #include <linux/mount.h> | 15 | #include <linux/mount.h> |
| 16 | #include <linux/smp_lock.h> | ||
| 17 | #include <asm/current.h> | 16 | #include <asm/current.h> |
| 18 | #include <asm/uaccess.h> | 17 | #include <asm/uaccess.h> |
| 19 | 18 | ||
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 0ddf7e55abe1..9714db393efe 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
| @@ -93,20 +93,20 @@ typedef unsigned int ext4_group_t; | |||
| 93 | struct ext4_allocation_request { | 93 | struct ext4_allocation_request { |
| 94 | /* target inode for block we're allocating */ | 94 | /* target inode for block we're allocating */ |
| 95 | struct inode *inode; | 95 | struct inode *inode; |
| 96 | /* how many blocks we want to allocate */ | ||
| 97 | unsigned int len; | ||
| 96 | /* logical block in target inode */ | 98 | /* logical block in target inode */ |
| 97 | ext4_lblk_t logical; | 99 | ext4_lblk_t logical; |
| 98 | /* phys. target (a hint) */ | ||
| 99 | ext4_fsblk_t goal; | ||
| 100 | /* the closest logical allocated block to the left */ | 100 | /* the closest logical allocated block to the left */ |
| 101 | ext4_lblk_t lleft; | 101 | ext4_lblk_t lleft; |
| 102 | /* phys. block for ^^^ */ | ||
| 103 | ext4_fsblk_t pleft; | ||
| 104 | /* the closest logical allocated block to the right */ | 102 | /* the closest logical allocated block to the right */ |
| 105 | ext4_lblk_t lright; | 103 | ext4_lblk_t lright; |
| 106 | /* phys. block for ^^^ */ | 104 | /* phys. target (a hint) */ |
| 105 | ext4_fsblk_t goal; | ||
| 106 | /* phys. block for the closest logical allocated block to the left */ | ||
| 107 | ext4_fsblk_t pleft; | ||
| 108 | /* phys. block for the closest logical allocated block to the right */ | ||
| 107 | ext4_fsblk_t pright; | 109 | ext4_fsblk_t pright; |
| 108 | /* how many blocks we want to allocate */ | ||
| 109 | unsigned int len; | ||
| 110 | /* flags. see above EXT4_MB_HINT_* */ | 110 | /* flags. see above EXT4_MB_HINT_* */ |
| 111 | unsigned int flags; | 111 | unsigned int flags; |
| 112 | }; | 112 | }; |
diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c index ad13a84644e1..eb27fd0f2ee8 100644 --- a/fs/ext4/ext4_jbd2.c +++ b/fs/ext4/ext4_jbd2.c | |||
| @@ -43,6 +43,8 @@ int __ext4_journal_forget(const char *where, handle_t *handle, | |||
| 43 | ext4_journal_abort_handle(where, __func__, bh, | 43 | ext4_journal_abort_handle(where, __func__, bh, |
| 44 | handle, err); | 44 | handle, err); |
| 45 | } | 45 | } |
| 46 | else | ||
| 47 | brelse(bh); | ||
| 46 | return err; | 48 | return err; |
| 47 | } | 49 | } |
| 48 | 50 | ||
| @@ -57,6 +59,8 @@ int __ext4_journal_revoke(const char *where, handle_t *handle, | |||
| 57 | ext4_journal_abort_handle(where, __func__, bh, | 59 | ext4_journal_abort_handle(where, __func__, bh, |
| 58 | handle, err); | 60 | handle, err); |
| 59 | } | 61 | } |
| 62 | else | ||
| 63 | brelse(bh); | ||
| 60 | return err; | 64 | return err; |
| 61 | } | 65 | } |
| 62 | 66 | ||
diff --git a/fs/ext4/ext4_jbd2.h b/fs/ext4/ext4_jbd2.h index be2f426f6805..139fb8cb87e4 100644 --- a/fs/ext4/ext4_jbd2.h +++ b/fs/ext4/ext4_jbd2.h | |||
| @@ -131,9 +131,11 @@ int __ext4_journal_get_undo_access(const char *where, handle_t *handle, | |||
| 131 | int __ext4_journal_get_write_access(const char *where, handle_t *handle, | 131 | int __ext4_journal_get_write_access(const char *where, handle_t *handle, |
| 132 | struct buffer_head *bh); | 132 | struct buffer_head *bh); |
| 133 | 133 | ||
| 134 | /* When called with an invalid handle, this will still do a put on the BH */ | ||
| 134 | int __ext4_journal_forget(const char *where, handle_t *handle, | 135 | int __ext4_journal_forget(const char *where, handle_t *handle, |
| 135 | struct buffer_head *bh); | 136 | struct buffer_head *bh); |
| 136 | 137 | ||
| 138 | /* When called with an invalid handle, this will still do a put on the BH */ | ||
| 137 | int __ext4_journal_revoke(const char *where, handle_t *handle, | 139 | int __ext4_journal_revoke(const char *where, handle_t *handle, |
| 138 | ext4_fsblk_t blocknr, struct buffer_head *bh); | 140 | ext4_fsblk_t blocknr, struct buffer_head *bh); |
| 139 | 141 | ||
| @@ -281,10 +283,10 @@ static inline int ext4_should_order_data(struct inode *inode) | |||
| 281 | 283 | ||
| 282 | static inline int ext4_should_writeback_data(struct inode *inode) | 284 | static inline int ext4_should_writeback_data(struct inode *inode) |
| 283 | { | 285 | { |
| 284 | if (EXT4_JOURNAL(inode) == NULL) | ||
| 285 | return 0; | ||
| 286 | if (!S_ISREG(inode->i_mode)) | 286 | if (!S_ISREG(inode->i_mode)) |
| 287 | return 0; | 287 | return 0; |
| 288 | if (EXT4_JOURNAL(inode) == NULL) | ||
| 289 | return 1; | ||
| 288 | if (EXT4_I(inode)->i_flags & EXT4_JOURNAL_DATA_FL) | 290 | if (EXT4_I(inode)->i_flags & EXT4_JOURNAL_DATA_FL) |
| 289 | return 0; | 291 | return 0; |
| 290 | if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA) | 292 | if (test_opt(inode->i_sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA) |
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 50322a09bd01..73ebfb44ad75 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
| @@ -1977,6 +1977,7 @@ int ext4_ext_calc_credits_for_single_extent(struct inode *inode, int nrblocks, | |||
| 1977 | */ | 1977 | */ |
| 1978 | /* 1 bitmap, 1 block group descriptor */ | 1978 | /* 1 bitmap, 1 block group descriptor */ |
| 1979 | ret = 2 + EXT4_META_TRANS_BLOCKS(inode->i_sb); | 1979 | ret = 2 + EXT4_META_TRANS_BLOCKS(inode->i_sb); |
| 1980 | return ret; | ||
| 1980 | } | 1981 | } |
| 1981 | } | 1982 | } |
| 1982 | 1983 | ||
diff --git a/fs/ext4/ialloc.c b/fs/ext4/ialloc.c index 2f645732e3b7..29e6dc7299b8 100644 --- a/fs/ext4/ialloc.c +++ b/fs/ext4/ialloc.c | |||
| @@ -833,7 +833,7 @@ struct inode *ext4_new_inode(handle_t *handle, struct inode *dir, int mode, | |||
| 833 | if (!goal) | 833 | if (!goal) |
| 834 | goal = sbi->s_inode_goal; | 834 | goal = sbi->s_inode_goal; |
| 835 | 835 | ||
| 836 | if (goal && goal < le32_to_cpu(sbi->s_es->s_inodes_count)) { | 836 | if (goal && goal <= le32_to_cpu(sbi->s_es->s_inodes_count)) { |
| 837 | group = (goal - 1) / EXT4_INODES_PER_GROUP(sb); | 837 | group = (goal - 1) / EXT4_INODES_PER_GROUP(sb); |
| 838 | ino = (goal - 1) % EXT4_INODES_PER_GROUP(sb); | 838 | ino = (goal - 1) % EXT4_INODES_PER_GROUP(sb); |
| 839 | ret2 = 0; | 839 | ret2 = 0; |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 60a26f3a6f8b..f9c642b22efa 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
| @@ -78,16 +78,14 @@ static int ext4_inode_is_fast_symlink(struct inode *inode) | |||
| 78 | * but there may still be a record of it in the journal, and that record | 78 | * but there may still be a record of it in the journal, and that record |
| 79 | * still needs to be revoked. | 79 | * still needs to be revoked. |
| 80 | * | 80 | * |
| 81 | * If the handle isn't valid we're not journaling so there's nothing to do. | 81 | * If the handle isn't valid we're not journaling, but we still need to |
| 82 | * call into ext4_journal_revoke() to put the buffer head. | ||
| 82 | */ | 83 | */ |
| 83 | int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode, | 84 | int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode, |
| 84 | struct buffer_head *bh, ext4_fsblk_t blocknr) | 85 | struct buffer_head *bh, ext4_fsblk_t blocknr) |
| 85 | { | 86 | { |
| 86 | int err; | 87 | int err; |
| 87 | 88 | ||
| 88 | if (!ext4_handle_valid(handle)) | ||
| 89 | return 0; | ||
| 90 | |||
| 91 | might_sleep(); | 89 | might_sleep(); |
| 92 | 90 | ||
| 93 | BUFFER_TRACE(bh, "enter"); | 91 | BUFFER_TRACE(bh, "enter"); |
| @@ -1513,14 +1511,14 @@ retry: | |||
| 1513 | * Add inode to orphan list in case we crash before | 1511 | * Add inode to orphan list in case we crash before |
| 1514 | * truncate finishes | 1512 | * truncate finishes |
| 1515 | */ | 1513 | */ |
| 1516 | if (pos + len > inode->i_size) | 1514 | if (pos + len > inode->i_size && ext4_can_truncate(inode)) |
| 1517 | ext4_orphan_add(handle, inode); | 1515 | ext4_orphan_add(handle, inode); |
| 1518 | 1516 | ||
| 1519 | ext4_journal_stop(handle); | 1517 | ext4_journal_stop(handle); |
| 1520 | if (pos + len > inode->i_size) { | 1518 | if (pos + len > inode->i_size) { |
| 1521 | vmtruncate(inode, inode->i_size); | 1519 | ext4_truncate(inode); |
| 1522 | /* | 1520 | /* |
| 1523 | * If vmtruncate failed early the inode might | 1521 | * If truncate failed early the inode might |
| 1524 | * still be on the orphan list; we need to | 1522 | * still be on the orphan list; we need to |
| 1525 | * make sure the inode is removed from the | 1523 | * make sure the inode is removed from the |
| 1526 | * orphan list in that case. | 1524 | * orphan list in that case. |
| @@ -1614,7 +1612,7 @@ static int ext4_ordered_write_end(struct file *file, | |||
| 1614 | ret2 = ext4_generic_write_end(file, mapping, pos, len, copied, | 1612 | ret2 = ext4_generic_write_end(file, mapping, pos, len, copied, |
| 1615 | page, fsdata); | 1613 | page, fsdata); |
| 1616 | copied = ret2; | 1614 | copied = ret2; |
| 1617 | if (pos + len > inode->i_size) | 1615 | if (pos + len > inode->i_size && ext4_can_truncate(inode)) |
| 1618 | /* if we have allocated more blocks and copied | 1616 | /* if we have allocated more blocks and copied |
| 1619 | * less. We will have blocks allocated outside | 1617 | * less. We will have blocks allocated outside |
| 1620 | * inode->i_size. So truncate them | 1618 | * inode->i_size. So truncate them |
| @@ -1628,9 +1626,9 @@ static int ext4_ordered_write_end(struct file *file, | |||
| 1628 | ret = ret2; | 1626 | ret = ret2; |
| 1629 | 1627 | ||
| 1630 | if (pos + len > inode->i_size) { | 1628 | if (pos + len > inode->i_size) { |
| 1631 | vmtruncate(inode, inode->i_size); | 1629 | ext4_truncate(inode); |
| 1632 | /* | 1630 | /* |
| 1633 | * If vmtruncate failed early the inode might still be | 1631 | * If truncate failed early the inode might still be |
| 1634 | * on the orphan list; we need to make sure the inode | 1632 | * on the orphan list; we need to make sure the inode |
| 1635 | * is removed from the orphan list in that case. | 1633 | * is removed from the orphan list in that case. |
| 1636 | */ | 1634 | */ |
| @@ -1655,7 +1653,7 @@ static int ext4_writeback_write_end(struct file *file, | |||
| 1655 | ret2 = ext4_generic_write_end(file, mapping, pos, len, copied, | 1653 | ret2 = ext4_generic_write_end(file, mapping, pos, len, copied, |
| 1656 | page, fsdata); | 1654 | page, fsdata); |
| 1657 | copied = ret2; | 1655 | copied = ret2; |
| 1658 | if (pos + len > inode->i_size) | 1656 | if (pos + len > inode->i_size && ext4_can_truncate(inode)) |
| 1659 | /* if we have allocated more blocks and copied | 1657 | /* if we have allocated more blocks and copied |
| 1660 | * less. We will have blocks allocated outside | 1658 | * less. We will have blocks allocated outside |
| 1661 | * inode->i_size. So truncate them | 1659 | * inode->i_size. So truncate them |
| @@ -1670,9 +1668,9 @@ static int ext4_writeback_write_end(struct file *file, | |||
| 1670 | ret = ret2; | 1668 | ret = ret2; |
| 1671 | 1669 | ||
| 1672 | if (pos + len > inode->i_size) { | 1670 | if (pos + len > inode->i_size) { |
| 1673 | vmtruncate(inode, inode->i_size); | 1671 | ext4_truncate(inode); |
| 1674 | /* | 1672 | /* |
| 1675 | * If vmtruncate failed early the inode might still be | 1673 | * If truncate failed early the inode might still be |
| 1676 | * on the orphan list; we need to make sure the inode | 1674 | * on the orphan list; we need to make sure the inode |
| 1677 | * is removed from the orphan list in that case. | 1675 | * is removed from the orphan list in that case. |
| 1678 | */ | 1676 | */ |
| @@ -1722,7 +1720,7 @@ static int ext4_journalled_write_end(struct file *file, | |||
| 1722 | 1720 | ||
| 1723 | unlock_page(page); | 1721 | unlock_page(page); |
| 1724 | page_cache_release(page); | 1722 | page_cache_release(page); |
| 1725 | if (pos + len > inode->i_size) | 1723 | if (pos + len > inode->i_size && ext4_can_truncate(inode)) |
| 1726 | /* if we have allocated more blocks and copied | 1724 | /* if we have allocated more blocks and copied |
| 1727 | * less. We will have blocks allocated outside | 1725 | * less. We will have blocks allocated outside |
| 1728 | * inode->i_size. So truncate them | 1726 | * inode->i_size. So truncate them |
| @@ -1733,9 +1731,9 @@ static int ext4_journalled_write_end(struct file *file, | |||
| 1733 | if (!ret) | 1731 | if (!ret) |
| 1734 | ret = ret2; | 1732 | ret = ret2; |
| 1735 | if (pos + len > inode->i_size) { | 1733 | if (pos + len > inode->i_size) { |
| 1736 | vmtruncate(inode, inode->i_size); | 1734 | ext4_truncate(inode); |
| 1737 | /* | 1735 | /* |
| 1738 | * If vmtruncate failed early the inode might still be | 1736 | * If truncate failed early the inode might still be |
| 1739 | * on the orphan list; we need to make sure the inode | 1737 | * on the orphan list; we need to make sure the inode |
| 1740 | * is removed from the orphan list in that case. | 1738 | * is removed from the orphan list in that case. |
| 1741 | */ | 1739 | */ |
| @@ -2305,15 +2303,9 @@ flush_it: | |||
| 2305 | return; | 2303 | return; |
| 2306 | } | 2304 | } |
| 2307 | 2305 | ||
| 2308 | static int ext4_bh_unmapped_or_delay(handle_t *handle, struct buffer_head *bh) | 2306 | static int ext4_bh_delay_or_unwritten(handle_t *handle, struct buffer_head *bh) |
| 2309 | { | 2307 | { |
| 2310 | /* | 2308 | return (buffer_delay(bh) || buffer_unwritten(bh)) && buffer_dirty(bh); |
| 2311 | * unmapped buffer is possible for holes. | ||
| 2312 | * delay buffer is possible with delayed allocation. | ||
| 2313 | * We also need to consider unwritten buffer as unmapped. | ||
| 2314 | */ | ||
| 2315 | return (!buffer_mapped(bh) || buffer_delay(bh) || | ||
| 2316 | buffer_unwritten(bh)) && buffer_dirty(bh); | ||
| 2317 | } | 2309 | } |
| 2318 | 2310 | ||
| 2319 | /* | 2311 | /* |
| @@ -2398,9 +2390,9 @@ static int __mpage_da_writepage(struct page *page, | |||
| 2398 | * We need to try to allocate | 2390 | * We need to try to allocate |
| 2399 | * unmapped blocks in the same page. | 2391 | * unmapped blocks in the same page. |
| 2400 | * Otherwise we won't make progress | 2392 | * Otherwise we won't make progress |
| 2401 | * with the page in ext4_da_writepage | 2393 | * with the page in ext4_writepage |
| 2402 | */ | 2394 | */ |
| 2403 | if (ext4_bh_unmapped_or_delay(NULL, bh)) { | 2395 | if (ext4_bh_delay_or_unwritten(NULL, bh)) { |
| 2404 | mpage_add_bh_to_extent(mpd, logical, | 2396 | mpage_add_bh_to_extent(mpd, logical, |
| 2405 | bh->b_size, | 2397 | bh->b_size, |
| 2406 | bh->b_state); | 2398 | bh->b_state); |
| @@ -2517,7 +2509,6 @@ static int noalloc_get_block_write(struct inode *inode, sector_t iblock, | |||
| 2517 | * so call get_block_wrap with create = 0 | 2509 | * so call get_block_wrap with create = 0 |
| 2518 | */ | 2510 | */ |
| 2519 | ret = ext4_get_blocks(NULL, inode, iblock, max_blocks, bh_result, 0); | 2511 | ret = ext4_get_blocks(NULL, inode, iblock, max_blocks, bh_result, 0); |
| 2520 | BUG_ON(create && ret == 0); | ||
| 2521 | if (ret > 0) { | 2512 | if (ret > 0) { |
| 2522 | bh_result->b_size = (ret << inode->i_blkbits); | 2513 | bh_result->b_size = (ret << inode->i_blkbits); |
| 2523 | ret = 0; | 2514 | ret = 0; |
| @@ -2525,15 +2516,102 @@ static int noalloc_get_block_write(struct inode *inode, sector_t iblock, | |||
| 2525 | return ret; | 2516 | return ret; |
| 2526 | } | 2517 | } |
| 2527 | 2518 | ||
| 2519 | static int bget_one(handle_t *handle, struct buffer_head *bh) | ||
| 2520 | { | ||
| 2521 | get_bh(bh); | ||
| 2522 | return 0; | ||
| 2523 | } | ||
| 2524 | |||
| 2525 | static int bput_one(handle_t *handle, struct buffer_head *bh) | ||
| 2526 | { | ||
| 2527 | put_bh(bh); | ||
| 2528 | return 0; | ||
| 2529 | } | ||
| 2530 | |||
| 2531 | static int __ext4_journalled_writepage(struct page *page, | ||
| 2532 | struct writeback_control *wbc, | ||
| 2533 | unsigned int len) | ||
| 2534 | { | ||
| 2535 | struct address_space *mapping = page->mapping; | ||
| 2536 | struct inode *inode = mapping->host; | ||
| 2537 | struct buffer_head *page_bufs; | ||
| 2538 | handle_t *handle = NULL; | ||
| 2539 | int ret = 0; | ||
| 2540 | int err; | ||
| 2541 | |||
| 2542 | page_bufs = page_buffers(page); | ||
| 2543 | BUG_ON(!page_bufs); | ||
| 2544 | walk_page_buffers(handle, page_bufs, 0, len, NULL, bget_one); | ||
| 2545 | /* As soon as we unlock the page, it can go away, but we have | ||
| 2546 | * references to buffers so we are safe */ | ||
| 2547 | unlock_page(page); | ||
| 2548 | |||
| 2549 | handle = ext4_journal_start(inode, ext4_writepage_trans_blocks(inode)); | ||
| 2550 | if (IS_ERR(handle)) { | ||
| 2551 | ret = PTR_ERR(handle); | ||
| 2552 | goto out; | ||
| 2553 | } | ||
| 2554 | |||
| 2555 | ret = walk_page_buffers(handle, page_bufs, 0, len, NULL, | ||
| 2556 | do_journal_get_write_access); | ||
| 2557 | |||
| 2558 | err = walk_page_buffers(handle, page_bufs, 0, len, NULL, | ||
| 2559 | write_end_fn); | ||
| 2560 | if (ret == 0) | ||
| 2561 | ret = err; | ||
| 2562 | err = ext4_journal_stop(handle); | ||
| 2563 | if (!ret) | ||
| 2564 | ret = err; | ||
| 2565 | |||
| 2566 | walk_page_buffers(handle, page_bufs, 0, len, NULL, bput_one); | ||
| 2567 | EXT4_I(inode)->i_state |= EXT4_STATE_JDATA; | ||
| 2568 | out: | ||
| 2569 | return ret; | ||
| 2570 | } | ||
| 2571 | |||
| 2528 | /* | 2572 | /* |
| 2573 | * Note that we don't need to start a transaction unless we're journaling data | ||
| 2574 | * because we should have holes filled from ext4_page_mkwrite(). We even don't | ||
| 2575 | * need to file the inode to the transaction's list in ordered mode because if | ||
| 2576 | * we are writing back data added by write(), the inode is already there and if | ||
| 2577 | * we are writing back data modified via mmap(), noone guarantees in which | ||
| 2578 | * transaction the data will hit the disk. In case we are journaling data, we | ||
| 2579 | * cannot start transaction directly because transaction start ranks above page | ||
| 2580 | * lock so we have to do some magic. | ||
| 2581 | * | ||
| 2529 | * This function can get called via... | 2582 | * This function can get called via... |
| 2530 | * - ext4_da_writepages after taking page lock (have journal handle) | 2583 | * - ext4_da_writepages after taking page lock (have journal handle) |
| 2531 | * - journal_submit_inode_data_buffers (no journal handle) | 2584 | * - journal_submit_inode_data_buffers (no journal handle) |
| 2532 | * - shrink_page_list via pdflush (no journal handle) | 2585 | * - shrink_page_list via pdflush (no journal handle) |
| 2533 | * - grab_page_cache when doing write_begin (have journal handle) | 2586 | * - grab_page_cache when doing write_begin (have journal handle) |
| 2587 | * | ||
| 2588 | * We don't do any block allocation in this function. If we have page with | ||
| 2589 | * multiple blocks we need to write those buffer_heads that are mapped. This | ||
| 2590 | * is important for mmaped based write. So if we do with blocksize 1K | ||
| 2591 | * truncate(f, 1024); | ||
| 2592 | * a = mmap(f, 0, 4096); | ||
| 2593 | * a[0] = 'a'; | ||
| 2594 | * truncate(f, 4096); | ||
| 2595 | * we have in the page first buffer_head mapped via page_mkwrite call back | ||
| 2596 | * but other bufer_heads would be unmapped but dirty(dirty done via the | ||
| 2597 | * do_wp_page). So writepage should write the first block. If we modify | ||
| 2598 | * the mmap area beyond 1024 we will again get a page_fault and the | ||
| 2599 | * page_mkwrite callback will do the block allocation and mark the | ||
| 2600 | * buffer_heads mapped. | ||
| 2601 | * | ||
| 2602 | * We redirty the page if we have any buffer_heads that is either delay or | ||
| 2603 | * unwritten in the page. | ||
| 2604 | * | ||
| 2605 | * We can get recursively called as show below. | ||
| 2606 | * | ||
| 2607 | * ext4_writepage() -> kmalloc() -> __alloc_pages() -> page_launder() -> | ||
| 2608 | * ext4_writepage() | ||
| 2609 | * | ||
| 2610 | * But since we don't do any block allocation we should not deadlock. | ||
| 2611 | * Page also have the dirty flag cleared so we don't get recurive page_lock. | ||
| 2534 | */ | 2612 | */ |
| 2535 | static int ext4_da_writepage(struct page *page, | 2613 | static int ext4_writepage(struct page *page, |
| 2536 | struct writeback_control *wbc) | 2614 | struct writeback_control *wbc) |
| 2537 | { | 2615 | { |
| 2538 | int ret = 0; | 2616 | int ret = 0; |
| 2539 | loff_t size; | 2617 | loff_t size; |
| @@ -2541,7 +2619,7 @@ static int ext4_da_writepage(struct page *page, | |||
| 2541 | struct buffer_head *page_bufs; | 2619 | struct buffer_head *page_bufs; |
| 2542 | struct inode *inode = page->mapping->host; | 2620 | struct inode *inode = page->mapping->host; |
| 2543 | 2621 | ||
| 2544 | trace_ext4_da_writepage(inode, page); | 2622 | trace_ext4_writepage(inode, page); |
| 2545 | size = i_size_read(inode); | 2623 | size = i_size_read(inode); |
| 2546 | if (page->index == size >> PAGE_CACHE_SHIFT) | 2624 | if (page->index == size >> PAGE_CACHE_SHIFT) |
| 2547 | len = size & ~PAGE_CACHE_MASK; | 2625 | len = size & ~PAGE_CACHE_MASK; |
| @@ -2551,7 +2629,7 @@ static int ext4_da_writepage(struct page *page, | |||
| 2551 | if (page_has_buffers(page)) { | 2629 | if (page_has_buffers(page)) { |
| 2552 | page_bufs = page_buffers(page); | 2630 | page_bufs = page_buffers(page); |
| 2553 | if (walk_page_buffers(NULL, page_bufs, 0, len, NULL, | 2631 | if (walk_page_buffers(NULL, page_bufs, 0, len, NULL, |
| 2554 | ext4_bh_unmapped_or_delay)) { | 2632 | ext4_bh_delay_or_unwritten)) { |
| 2555 | /* | 2633 | /* |
| 2556 | * We don't want to do block allocation | 2634 | * We don't want to do block allocation |
| 2557 | * So redirty the page and return | 2635 | * So redirty the page and return |
| @@ -2578,13 +2656,13 @@ static int ext4_da_writepage(struct page *page, | |||
| 2578 | * all are mapped and non delay. We don't want to | 2656 | * all are mapped and non delay. We don't want to |
| 2579 | * do block allocation here. | 2657 | * do block allocation here. |
| 2580 | */ | 2658 | */ |
| 2581 | ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE, | 2659 | ret = block_prepare_write(page, 0, len, |
| 2582 | noalloc_get_block_write); | 2660 | noalloc_get_block_write); |
| 2583 | if (!ret) { | 2661 | if (!ret) { |
| 2584 | page_bufs = page_buffers(page); | 2662 | page_bufs = page_buffers(page); |
| 2585 | /* check whether all are mapped and non delay */ | 2663 | /* check whether all are mapped and non delay */ |
| 2586 | if (walk_page_buffers(NULL, page_bufs, 0, len, NULL, | 2664 | if (walk_page_buffers(NULL, page_bufs, 0, len, NULL, |
| 2587 | ext4_bh_unmapped_or_delay)) { | 2665 | ext4_bh_delay_or_unwritten)) { |
| 2588 | redirty_page_for_writepage(wbc, page); | 2666 | redirty_page_for_writepage(wbc, page); |
| 2589 | unlock_page(page); | 2667 | unlock_page(page); |
| 2590 | return 0; | 2668 | return 0; |
| @@ -2600,7 +2678,16 @@ static int ext4_da_writepage(struct page *page, | |||
| 2600 | return 0; | 2678 | return 0; |
| 2601 | } | 2679 | } |
| 2602 | /* now mark the buffer_heads as dirty and uptodate */ | 2680 | /* now mark the buffer_heads as dirty and uptodate */ |
| 2603 | block_commit_write(page, 0, PAGE_CACHE_SIZE); | 2681 | block_commit_write(page, 0, len); |
| 2682 | } | ||
| 2683 | |||
| 2684 | if (PageChecked(page) && ext4_should_journal_data(inode)) { | ||
| 2685 | /* | ||
| 2686 | * It's mmapped pagecache. Add buffers and journal it. There | ||
| 2687 | * doesn't seem much point in redirtying the page here. | ||
| 2688 | */ | ||
| 2689 | ClearPageChecked(page); | ||
| 2690 | return __ext4_journalled_writepage(page, wbc, len); | ||
| 2604 | } | 2691 | } |
| 2605 | 2692 | ||
| 2606 | if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode)) | 2693 | if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode)) |
| @@ -2907,7 +2994,7 @@ retry: | |||
| 2907 | * i_size_read because we hold i_mutex. | 2994 | * i_size_read because we hold i_mutex. |
| 2908 | */ | 2995 | */ |
| 2909 | if (pos + len > inode->i_size) | 2996 | if (pos + len > inode->i_size) |
| 2910 | vmtruncate(inode, inode->i_size); | 2997 | ext4_truncate(inode); |
| 2911 | } | 2998 | } |
| 2912 | 2999 | ||
| 2913 | if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) | 3000 | if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) |
| @@ -3130,222 +3217,6 @@ static sector_t ext4_bmap(struct address_space *mapping, sector_t block) | |||
| 3130 | return generic_block_bmap(mapping, block, ext4_get_block); | 3217 | return generic_block_bmap(mapping, block, ext4_get_block); |
| 3131 | } | 3218 | } |
| 3132 | 3219 | ||
| 3133 | static int bget_one(handle_t *handle, struct buffer_head *bh) | ||
| 3134 | { | ||
| 3135 | get_bh(bh); | ||
| 3136 | return 0; | ||
| 3137 | } | ||
| 3138 | |||
| 3139 | static int bput_one(handle_t *handle, struct buffer_head *bh) | ||
| 3140 | { | ||
| 3141 | put_bh(bh); | ||
| 3142 | return 0; | ||
| 3143 | } | ||
| 3144 | |||
| 3145 | /* | ||
| 3146 | * Note that we don't need to start a transaction unless we're journaling data | ||
| 3147 | * because we should have holes filled from ext4_page_mkwrite(). We even don't | ||
| 3148 | * need to file the inode to the transaction's list in ordered mode because if | ||
| 3149 | * we are writing back data added by write(), the inode is already there and if | ||
| 3150 | * we are writing back data modified via mmap(), noone guarantees in which | ||
| 3151 | * transaction the data will hit the disk. In case we are journaling data, we | ||
| 3152 | * cannot start transaction directly because transaction start ranks above page | ||
| 3153 | * lock so we have to do some magic. | ||
| 3154 | * | ||
| 3155 | * In all journaling modes block_write_full_page() will start the I/O. | ||
| 3156 | * | ||
| 3157 | * Problem: | ||
| 3158 | * | ||
| 3159 | * ext4_writepage() -> kmalloc() -> __alloc_pages() -> page_launder() -> | ||
| 3160 | * ext4_writepage() | ||
| 3161 | * | ||
| 3162 | * Similar for: | ||
| 3163 | * | ||
| 3164 | * ext4_file_write() -> generic_file_write() -> __alloc_pages() -> ... | ||
| 3165 | * | ||
| 3166 | * Same applies to ext4_get_block(). We will deadlock on various things like | ||
| 3167 | * lock_journal and i_data_sem | ||
| 3168 | * | ||
| 3169 | * Setting PF_MEMALLOC here doesn't work - too many internal memory | ||
| 3170 | * allocations fail. | ||
| 3171 | * | ||
| 3172 | * 16May01: If we're reentered then journal_current_handle() will be | ||
| 3173 | * non-zero. We simply *return*. | ||
| 3174 | * | ||
| 3175 | * 1 July 2001: @@@ FIXME: | ||
| 3176 | * In journalled data mode, a data buffer may be metadata against the | ||
| 3177 | * current transaction. But the same file is part of a shared mapping | ||
| 3178 | * and someone does a writepage() on it. | ||
| 3179 | * | ||
| 3180 | * We will move the buffer onto the async_data list, but *after* it has | ||
| 3181 | * been dirtied. So there's a small window where we have dirty data on | ||
| 3182 | * BJ_Metadata. | ||
| 3183 | * | ||
| 3184 | * Note that this only applies to the last partial page in the file. The | ||
| 3185 | * bit which block_write_full_page() uses prepare/commit for. (That's | ||
| 3186 | * broken code anyway: it's wrong for msync()). | ||
| 3187 | * | ||
| 3188 | * It's a rare case: affects the final partial page, for journalled data | ||
| 3189 | * where the file is subject to bith write() and writepage() in the same | ||
| 3190 | * transction. To fix it we'll need a custom block_write_full_page(). | ||
| 3191 | * We'll probably need that anyway for journalling writepage() output. | ||
| 3192 | * | ||
| 3193 | * We don't honour synchronous mounts for writepage(). That would be | ||
| 3194 | * disastrous. Any write() or metadata operation will sync the fs for | ||
| 3195 | * us. | ||
| 3196 | * | ||
| 3197 | */ | ||
| 3198 | static int __ext4_normal_writepage(struct page *page, | ||
| 3199 | struct writeback_control *wbc) | ||
| 3200 | { | ||
| 3201 | struct inode *inode = page->mapping->host; | ||
| 3202 | |||
| 3203 | if (test_opt(inode->i_sb, NOBH)) | ||
| 3204 | return nobh_writepage(page, noalloc_get_block_write, wbc); | ||
| 3205 | else | ||
| 3206 | return block_write_full_page(page, noalloc_get_block_write, | ||
| 3207 | wbc); | ||
| 3208 | } | ||
| 3209 | |||
| 3210 | static int ext4_normal_writepage(struct page *page, | ||
| 3211 | struct writeback_control *wbc) | ||
| 3212 | { | ||
| 3213 | struct inode *inode = page->mapping->host; | ||
| 3214 | loff_t size = i_size_read(inode); | ||
| 3215 | loff_t len; | ||
| 3216 | |||
| 3217 | trace_ext4_normal_writepage(inode, page); | ||
| 3218 | J_ASSERT(PageLocked(page)); | ||
| 3219 | if (page->index == size >> PAGE_CACHE_SHIFT) | ||
| 3220 | len = size & ~PAGE_CACHE_MASK; | ||
| 3221 | else | ||
| 3222 | len = PAGE_CACHE_SIZE; | ||
| 3223 | |||
| 3224 | if (page_has_buffers(page)) { | ||
| 3225 | /* if page has buffers it should all be mapped | ||
| 3226 | * and allocated. If there are not buffers attached | ||
| 3227 | * to the page we know the page is dirty but it lost | ||
| 3228 | * buffers. That means that at some moment in time | ||
| 3229 | * after write_begin() / write_end() has been called | ||
| 3230 | * all buffers have been clean and thus they must have been | ||
| 3231 | * written at least once. So they are all mapped and we can | ||
| 3232 | * happily proceed with mapping them and writing the page. | ||
| 3233 | */ | ||
| 3234 | BUG_ON(walk_page_buffers(NULL, page_buffers(page), 0, len, NULL, | ||
| 3235 | ext4_bh_unmapped_or_delay)); | ||
| 3236 | } | ||
| 3237 | |||
| 3238 | if (!ext4_journal_current_handle()) | ||
| 3239 | return __ext4_normal_writepage(page, wbc); | ||
| 3240 | |||
| 3241 | redirty_page_for_writepage(wbc, page); | ||
| 3242 | unlock_page(page); | ||
| 3243 | return 0; | ||
| 3244 | } | ||
| 3245 | |||
| 3246 | static int __ext4_journalled_writepage(struct page *page, | ||
| 3247 | struct writeback_control *wbc) | ||
| 3248 | { | ||
| 3249 | struct address_space *mapping = page->mapping; | ||
| 3250 | struct inode *inode = mapping->host; | ||
| 3251 | struct buffer_head *page_bufs; | ||
| 3252 | handle_t *handle = NULL; | ||
| 3253 | int ret = 0; | ||
| 3254 | int err; | ||
| 3255 | |||
| 3256 | ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE, | ||
| 3257 | noalloc_get_block_write); | ||
| 3258 | if (ret != 0) | ||
| 3259 | goto out_unlock; | ||
| 3260 | |||
| 3261 | page_bufs = page_buffers(page); | ||
| 3262 | walk_page_buffers(handle, page_bufs, 0, PAGE_CACHE_SIZE, NULL, | ||
| 3263 | bget_one); | ||
| 3264 | /* As soon as we unlock the page, it can go away, but we have | ||
| 3265 | * references to buffers so we are safe */ | ||
| 3266 | unlock_page(page); | ||
| 3267 | |||
| 3268 | handle = ext4_journal_start(inode, ext4_writepage_trans_blocks(inode)); | ||
| 3269 | if (IS_ERR(handle)) { | ||
| 3270 | ret = PTR_ERR(handle); | ||
| 3271 | goto out; | ||
| 3272 | } | ||
| 3273 | |||
| 3274 | ret = walk_page_buffers(handle, page_bufs, 0, | ||
| 3275 | PAGE_CACHE_SIZE, NULL, do_journal_get_write_access); | ||
| 3276 | |||
| 3277 | err = walk_page_buffers(handle, page_bufs, 0, | ||
| 3278 | PAGE_CACHE_SIZE, NULL, write_end_fn); | ||
| 3279 | if (ret == 0) | ||
| 3280 | ret = err; | ||
| 3281 | err = ext4_journal_stop(handle); | ||
| 3282 | if (!ret) | ||
| 3283 | ret = err; | ||
| 3284 | |||
| 3285 | walk_page_buffers(handle, page_bufs, 0, | ||
| 3286 | PAGE_CACHE_SIZE, NULL, bput_one); | ||
| 3287 | EXT4_I(inode)->i_state |= EXT4_STATE_JDATA; | ||
| 3288 | goto out; | ||
| 3289 | |||
| 3290 | out_unlock: | ||
| 3291 | unlock_page(page); | ||
| 3292 | out: | ||
| 3293 | return ret; | ||
| 3294 | } | ||
| 3295 | |||
| 3296 | static int ext4_journalled_writepage(struct page *page, | ||
| 3297 | struct writeback_control *wbc) | ||
| 3298 | { | ||
| 3299 | struct inode *inode = page->mapping->host; | ||
| 3300 | loff_t size = i_size_read(inode); | ||
| 3301 | loff_t len; | ||
| 3302 | |||
| 3303 | trace_ext4_journalled_writepage(inode, page); | ||
| 3304 | J_ASSERT(PageLocked(page)); | ||
| 3305 | if (page->index == size >> PAGE_CACHE_SHIFT) | ||
| 3306 | len = size & ~PAGE_CACHE_MASK; | ||
| 3307 | else | ||
| 3308 | len = PAGE_CACHE_SIZE; | ||
| 3309 | |||
| 3310 | if (page_has_buffers(page)) { | ||
| 3311 | /* if page has buffers it should all be mapped | ||
| 3312 | * and allocated. If there are not buffers attached | ||
| 3313 | * to the page we know the page is dirty but it lost | ||
| 3314 | * buffers. That means that at some moment in time | ||
| 3315 | * after write_begin() / write_end() has been called | ||
| 3316 | * all buffers have been clean and thus they must have been | ||
| 3317 | * written at least once. So they are all mapped and we can | ||
| 3318 | * happily proceed with mapping them and writing the page. | ||
| 3319 | */ | ||
| 3320 | BUG_ON(walk_page_buffers(NULL, page_buffers(page), 0, len, NULL, | ||
| 3321 | ext4_bh_unmapped_or_delay)); | ||
| 3322 | } | ||
| 3323 | |||
| 3324 | if (ext4_journal_current_handle()) | ||
| 3325 | goto no_write; | ||
| 3326 | |||
| 3327 | if (PageChecked(page)) { | ||
| 3328 | /* | ||
| 3329 | * It's mmapped pagecache. Add buffers and journal it. There | ||
| 3330 | * doesn't seem much point in redirtying the page here. | ||
| 3331 | */ | ||
| 3332 | ClearPageChecked(page); | ||
| 3333 | return __ext4_journalled_writepage(page, wbc); | ||
| 3334 | } else { | ||
| 3335 | /* | ||
| 3336 | * It may be a page full of checkpoint-mode buffers. We don't | ||
| 3337 | * really know unless we go poke around in the buffer_heads. | ||
| 3338 | * But block_write_full_page will do the right thing. | ||
| 3339 | */ | ||
| 3340 | return block_write_full_page(page, noalloc_get_block_write, | ||
| 3341 | wbc); | ||
| 3342 | } | ||
| 3343 | no_write: | ||
| 3344 | redirty_page_for_writepage(wbc, page); | ||
| 3345 | unlock_page(page); | ||
| 3346 | return 0; | ||
| 3347 | } | ||
| 3348 | |||
| 3349 | static int ext4_readpage(struct file *file, struct page *page) | 3220 | static int ext4_readpage(struct file *file, struct page *page) |
| 3350 | { | 3221 | { |
| 3351 | return mpage_readpage(page, ext4_get_block); | 3222 | return mpage_readpage(page, ext4_get_block); |
| @@ -3492,7 +3363,7 @@ static int ext4_journalled_set_page_dirty(struct page *page) | |||
| 3492 | static const struct address_space_operations ext4_ordered_aops = { | 3363 | static const struct address_space_operations ext4_ordered_aops = { |
| 3493 | .readpage = ext4_readpage, | 3364 | .readpage = ext4_readpage, |
| 3494 | .readpages = ext4_readpages, | 3365 | .readpages = ext4_readpages, |
| 3495 | .writepage = ext4_normal_writepage, | 3366 | .writepage = ext4_writepage, |
| 3496 | .sync_page = block_sync_page, | 3367 | .sync_page = block_sync_page, |
| 3497 | .write_begin = ext4_write_begin, | 3368 | .write_begin = ext4_write_begin, |
| 3498 | .write_end = ext4_ordered_write_end, | 3369 | .write_end = ext4_ordered_write_end, |
| @@ -3507,7 +3378,7 @@ static const struct address_space_operations ext4_ordered_aops = { | |||
| 3507 | static const struct address_space_operations ext4_writeback_aops = { | 3378 | static const struct address_space_operations ext4_writeback_aops = { |
| 3508 | .readpage = ext4_readpage, | 3379 | .readpage = ext4_readpage, |
| 3509 | .readpages = ext4_readpages, | 3380 | .readpages = ext4_readpages, |
| 3510 | .writepage = ext4_normal_writepage, | 3381 | .writepage = ext4_writepage, |
| 3511 | .sync_page = block_sync_page, | 3382 | .sync_page = block_sync_page, |
| 3512 | .write_begin = ext4_write_begin, | 3383 | .write_begin = ext4_write_begin, |
| 3513 | .write_end = ext4_writeback_write_end, | 3384 | .write_end = ext4_writeback_write_end, |
| @@ -3522,7 +3393,7 @@ static const struct address_space_operations ext4_writeback_aops = { | |||
| 3522 | static const struct address_space_operations ext4_journalled_aops = { | 3393 | static const struct address_space_operations ext4_journalled_aops = { |
| 3523 | .readpage = ext4_readpage, | 3394 | .readpage = ext4_readpage, |
| 3524 | .readpages = ext4_readpages, | 3395 | .readpages = ext4_readpages, |
| 3525 | .writepage = ext4_journalled_writepage, | 3396 | .writepage = ext4_writepage, |
| 3526 | .sync_page = block_sync_page, | 3397 | .sync_page = block_sync_page, |
| 3527 | .write_begin = ext4_write_begin, | 3398 | .write_begin = ext4_write_begin, |
| 3528 | .write_end = ext4_journalled_write_end, | 3399 | .write_end = ext4_journalled_write_end, |
| @@ -3536,7 +3407,7 @@ static const struct address_space_operations ext4_journalled_aops = { | |||
| 3536 | static const struct address_space_operations ext4_da_aops = { | 3407 | static const struct address_space_operations ext4_da_aops = { |
| 3537 | .readpage = ext4_readpage, | 3408 | .readpage = ext4_readpage, |
| 3538 | .readpages = ext4_readpages, | 3409 | .readpages = ext4_readpages, |
| 3539 | .writepage = ext4_da_writepage, | 3410 | .writepage = ext4_writepage, |
| 3540 | .writepages = ext4_da_writepages, | 3411 | .writepages = ext4_da_writepages, |
| 3541 | .sync_page = block_sync_page, | 3412 | .sync_page = block_sync_page, |
| 3542 | .write_begin = ext4_da_write_begin, | 3413 | .write_begin = ext4_da_write_begin, |
| @@ -3583,7 +3454,8 @@ int ext4_block_truncate_page(handle_t *handle, | |||
| 3583 | struct page *page; | 3454 | struct page *page; |
| 3584 | int err = 0; | 3455 | int err = 0; |
| 3585 | 3456 | ||
| 3586 | page = grab_cache_page(mapping, from >> PAGE_CACHE_SHIFT); | 3457 | page = find_or_create_page(mapping, from >> PAGE_CACHE_SHIFT, |
| 3458 | mapping_gfp_mask(mapping) & ~__GFP_FS); | ||
| 3587 | if (!page) | 3459 | if (!page) |
| 3588 | return -EINVAL; | 3460 | return -EINVAL; |
| 3589 | 3461 | ||
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index bb415408fdb6..7050a9cd04a4 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c | |||
| @@ -12,7 +12,6 @@ | |||
| 12 | #include <linux/capability.h> | 12 | #include <linux/capability.h> |
| 13 | #include <linux/time.h> | 13 | #include <linux/time.h> |
| 14 | #include <linux/compat.h> | 14 | #include <linux/compat.h> |
| 15 | #include <linux/smp_lock.h> | ||
| 16 | #include <linux/mount.h> | 15 | #include <linux/mount.h> |
| 17 | #include <linux/file.h> | 16 | #include <linux/file.h> |
| 18 | #include <asm/uaccess.h> | 17 | #include <asm/uaccess.h> |
| @@ -192,7 +191,7 @@ setversion_out: | |||
| 192 | case EXT4_IOC_GROUP_EXTEND: { | 191 | case EXT4_IOC_GROUP_EXTEND: { |
| 193 | ext4_fsblk_t n_blocks_count; | 192 | ext4_fsblk_t n_blocks_count; |
| 194 | struct super_block *sb = inode->i_sb; | 193 | struct super_block *sb = inode->i_sb; |
| 195 | int err, err2; | 194 | int err, err2=0; |
| 196 | 195 | ||
| 197 | if (!capable(CAP_SYS_RESOURCE)) | 196 | if (!capable(CAP_SYS_RESOURCE)) |
| 198 | return -EPERM; | 197 | return -EPERM; |
| @@ -205,9 +204,11 @@ setversion_out: | |||
| 205 | return err; | 204 | return err; |
| 206 | 205 | ||
| 207 | err = ext4_group_extend(sb, EXT4_SB(sb)->s_es, n_blocks_count); | 206 | err = ext4_group_extend(sb, EXT4_SB(sb)->s_es, n_blocks_count); |
| 208 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); | 207 | if (EXT4_SB(sb)->s_journal) { |
| 209 | err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal); | 208 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); |
| 210 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); | 209 | err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal); |
| 210 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); | ||
| 211 | } | ||
| 211 | if (err == 0) | 212 | if (err == 0) |
| 212 | err = err2; | 213 | err = err2; |
| 213 | mnt_drop_write(filp->f_path.mnt); | 214 | mnt_drop_write(filp->f_path.mnt); |
| @@ -252,7 +253,7 @@ setversion_out: | |||
| 252 | case EXT4_IOC_GROUP_ADD: { | 253 | case EXT4_IOC_GROUP_ADD: { |
| 253 | struct ext4_new_group_data input; | 254 | struct ext4_new_group_data input; |
| 254 | struct super_block *sb = inode->i_sb; | 255 | struct super_block *sb = inode->i_sb; |
| 255 | int err, err2; | 256 | int err, err2=0; |
| 256 | 257 | ||
| 257 | if (!capable(CAP_SYS_RESOURCE)) | 258 | if (!capable(CAP_SYS_RESOURCE)) |
| 258 | return -EPERM; | 259 | return -EPERM; |
| @@ -266,9 +267,11 @@ setversion_out: | |||
| 266 | return err; | 267 | return err; |
| 267 | 268 | ||
| 268 | err = ext4_group_add(sb, &input); | 269 | err = ext4_group_add(sb, &input); |
| 269 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); | 270 | if (EXT4_SB(sb)->s_journal) { |
| 270 | err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal); | 271 | jbd2_journal_lock_updates(EXT4_SB(sb)->s_journal); |
| 271 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); | 272 | err2 = jbd2_journal_flush(EXT4_SB(sb)->s_journal); |
| 273 | jbd2_journal_unlock_updates(EXT4_SB(sb)->s_journal); | ||
| 274 | } | ||
| 272 | if (err == 0) | 275 | if (err == 0) |
| 273 | err = err2; | 276 | err = err2; |
| 274 | mnt_drop_write(filp->f_path.mnt); | 277 | mnt_drop_write(filp->f_path.mnt); |
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 519a0a686d94..cd258463e2a9 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
| @@ -657,7 +657,8 @@ static void ext4_mb_mark_free_simple(struct super_block *sb, | |||
| 657 | } | 657 | } |
| 658 | } | 658 | } |
| 659 | 659 | ||
| 660 | static void ext4_mb_generate_buddy(struct super_block *sb, | 660 | static noinline_for_stack |
| 661 | void ext4_mb_generate_buddy(struct super_block *sb, | ||
| 661 | void *buddy, void *bitmap, ext4_group_t group) | 662 | void *buddy, void *bitmap, ext4_group_t group) |
| 662 | { | 663 | { |
| 663 | struct ext4_group_info *grp = ext4_get_group_info(sb, group); | 664 | struct ext4_group_info *grp = ext4_get_group_info(sb, group); |
| @@ -1480,7 +1481,8 @@ static void ext4_mb_measure_extent(struct ext4_allocation_context *ac, | |||
| 1480 | ext4_mb_check_limits(ac, e4b, 0); | 1481 | ext4_mb_check_limits(ac, e4b, 0); |
| 1481 | } | 1482 | } |
| 1482 | 1483 | ||
| 1483 | static int ext4_mb_try_best_found(struct ext4_allocation_context *ac, | 1484 | static noinline_for_stack |
| 1485 | int ext4_mb_try_best_found(struct ext4_allocation_context *ac, | ||
| 1484 | struct ext4_buddy *e4b) | 1486 | struct ext4_buddy *e4b) |
| 1485 | { | 1487 | { |
| 1486 | struct ext4_free_extent ex = ac->ac_b_ex; | 1488 | struct ext4_free_extent ex = ac->ac_b_ex; |
| @@ -1507,7 +1509,8 @@ static int ext4_mb_try_best_found(struct ext4_allocation_context *ac, | |||
| 1507 | return 0; | 1509 | return 0; |
| 1508 | } | 1510 | } |
| 1509 | 1511 | ||
| 1510 | static int ext4_mb_find_by_goal(struct ext4_allocation_context *ac, | 1512 | static noinline_for_stack |
| 1513 | int ext4_mb_find_by_goal(struct ext4_allocation_context *ac, | ||
| 1511 | struct ext4_buddy *e4b) | 1514 | struct ext4_buddy *e4b) |
| 1512 | { | 1515 | { |
| 1513 | ext4_group_t group = ac->ac_g_ex.fe_group; | 1516 | ext4_group_t group = ac->ac_g_ex.fe_group; |
| @@ -1566,7 +1569,8 @@ static int ext4_mb_find_by_goal(struct ext4_allocation_context *ac, | |||
| 1566 | * The routine scans buddy structures (not bitmap!) from given order | 1569 | * The routine scans buddy structures (not bitmap!) from given order |
| 1567 | * to max order and tries to find big enough chunk to satisfy the req | 1570 | * to max order and tries to find big enough chunk to satisfy the req |
| 1568 | */ | 1571 | */ |
| 1569 | static void ext4_mb_simple_scan_group(struct ext4_allocation_context *ac, | 1572 | static noinline_for_stack |
| 1573 | void ext4_mb_simple_scan_group(struct ext4_allocation_context *ac, | ||
| 1570 | struct ext4_buddy *e4b) | 1574 | struct ext4_buddy *e4b) |
| 1571 | { | 1575 | { |
| 1572 | struct super_block *sb = ac->ac_sb; | 1576 | struct super_block *sb = ac->ac_sb; |
| @@ -1609,7 +1613,8 @@ static void ext4_mb_simple_scan_group(struct ext4_allocation_context *ac, | |||
| 1609 | * In order to optimize scanning, caller must pass number of | 1613 | * In order to optimize scanning, caller must pass number of |
| 1610 | * free blocks in the group, so the routine can know upper limit. | 1614 | * free blocks in the group, so the routine can know upper limit. |
| 1611 | */ | 1615 | */ |
| 1612 | static void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac, | 1616 | static noinline_for_stack |
| 1617 | void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac, | ||
| 1613 | struct ext4_buddy *e4b) | 1618 | struct ext4_buddy *e4b) |
| 1614 | { | 1619 | { |
| 1615 | struct super_block *sb = ac->ac_sb; | 1620 | struct super_block *sb = ac->ac_sb; |
| @@ -1668,7 +1673,8 @@ static void ext4_mb_complex_scan_group(struct ext4_allocation_context *ac, | |||
| 1668 | * we try to find stripe-aligned chunks for stripe-size requests | 1673 | * we try to find stripe-aligned chunks for stripe-size requests |
| 1669 | * XXX should do so at least for multiples of stripe size as well | 1674 | * XXX should do so at least for multiples of stripe size as well |
| 1670 | */ | 1675 | */ |
| 1671 | static void ext4_mb_scan_aligned(struct ext4_allocation_context *ac, | 1676 | static noinline_for_stack |
| 1677 | void ext4_mb_scan_aligned(struct ext4_allocation_context *ac, | ||
| 1672 | struct ext4_buddy *e4b) | 1678 | struct ext4_buddy *e4b) |
| 1673 | { | 1679 | { |
| 1674 | struct super_block *sb = ac->ac_sb; | 1680 | struct super_block *sb = ac->ac_sb; |
| @@ -1831,7 +1837,8 @@ void ext4_mb_put_buddy_cache_lock(struct super_block *sb, | |||
| 1831 | 1837 | ||
| 1832 | } | 1838 | } |
| 1833 | 1839 | ||
| 1834 | static int ext4_mb_init_group(struct super_block *sb, ext4_group_t group) | 1840 | static noinline_for_stack |
| 1841 | int ext4_mb_init_group(struct super_block *sb, ext4_group_t group) | ||
| 1835 | { | 1842 | { |
| 1836 | 1843 | ||
| 1837 | int ret; | 1844 | int ret; |
| @@ -2902,7 +2909,11 @@ int __init init_ext4_mballoc(void) | |||
| 2902 | 2909 | ||
| 2903 | void exit_ext4_mballoc(void) | 2910 | void exit_ext4_mballoc(void) |
| 2904 | { | 2911 | { |
| 2905 | /* XXX: synchronize_rcu(); */ | 2912 | /* |
| 2913 | * Wait for completion of call_rcu()'s on ext4_pspace_cachep | ||
| 2914 | * before destroying the slab cache. | ||
| 2915 | */ | ||
| 2916 | rcu_barrier(); | ||
| 2906 | kmem_cache_destroy(ext4_pspace_cachep); | 2917 | kmem_cache_destroy(ext4_pspace_cachep); |
| 2907 | kmem_cache_destroy(ext4_ac_cachep); | 2918 | kmem_cache_destroy(ext4_ac_cachep); |
| 2908 | kmem_cache_destroy(ext4_free_ext_cachep); | 2919 | kmem_cache_destroy(ext4_free_ext_cachep); |
| @@ -3457,7 +3468,8 @@ static void ext4_mb_generate_from_freelist(struct super_block *sb, void *bitmap, | |||
| 3457 | * used in in-core bitmap. buddy must be generated from this bitmap | 3468 | * used in in-core bitmap. buddy must be generated from this bitmap |
| 3458 | * Need to be called with ext4 group lock held | 3469 | * Need to be called with ext4 group lock held |
| 3459 | */ | 3470 | */ |
| 3460 | static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, | 3471 | static noinline_for_stack |
| 3472 | void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap, | ||
| 3461 | ext4_group_t group) | 3473 | ext4_group_t group) |
| 3462 | { | 3474 | { |
| 3463 | struct ext4_group_info *grp = ext4_get_group_info(sb, group); | 3475 | struct ext4_group_info *grp = ext4_get_group_info(sb, group); |
| @@ -4215,14 +4227,9 @@ ext4_mb_initialize_context(struct ext4_allocation_context *ac, | |||
| 4215 | ext4_get_group_no_and_offset(sb, goal, &group, &block); | 4227 | ext4_get_group_no_and_offset(sb, goal, &group, &block); |
| 4216 | 4228 | ||
| 4217 | /* set up allocation goals */ | 4229 | /* set up allocation goals */ |
| 4230 | memset(ac, 0, sizeof(struct ext4_allocation_context)); | ||
| 4218 | ac->ac_b_ex.fe_logical = ar->logical; | 4231 | ac->ac_b_ex.fe_logical = ar->logical; |
| 4219 | ac->ac_b_ex.fe_group = 0; | ||
| 4220 | ac->ac_b_ex.fe_start = 0; | ||
| 4221 | ac->ac_b_ex.fe_len = 0; | ||
| 4222 | ac->ac_status = AC_STATUS_CONTINUE; | 4232 | ac->ac_status = AC_STATUS_CONTINUE; |
| 4223 | ac->ac_groups_scanned = 0; | ||
| 4224 | ac->ac_ex_scanned = 0; | ||
| 4225 | ac->ac_found = 0; | ||
| 4226 | ac->ac_sb = sb; | 4233 | ac->ac_sb = sb; |
| 4227 | ac->ac_inode = ar->inode; | 4234 | ac->ac_inode = ar->inode; |
| 4228 | ac->ac_o_ex.fe_logical = ar->logical; | 4235 | ac->ac_o_ex.fe_logical = ar->logical; |
| @@ -4233,15 +4240,7 @@ ext4_mb_initialize_context(struct ext4_allocation_context *ac, | |||
| 4233 | ac->ac_g_ex.fe_group = group; | 4240 | ac->ac_g_ex.fe_group = group; |
| 4234 | ac->ac_g_ex.fe_start = block; | 4241 | ac->ac_g_ex.fe_start = block; |
| 4235 | ac->ac_g_ex.fe_len = len; | 4242 | ac->ac_g_ex.fe_len = len; |
| 4236 | ac->ac_f_ex.fe_len = 0; | ||
| 4237 | ac->ac_flags = ar->flags; | 4243 | ac->ac_flags = ar->flags; |
| 4238 | ac->ac_2order = 0; | ||
| 4239 | ac->ac_criteria = 0; | ||
| 4240 | ac->ac_pa = NULL; | ||
| 4241 | ac->ac_bitmap_page = NULL; | ||
| 4242 | ac->ac_buddy_page = NULL; | ||
| 4243 | ac->alloc_semp = NULL; | ||
| 4244 | ac->ac_lg = NULL; | ||
| 4245 | 4244 | ||
| 4246 | /* we have to define context: we'll we work with a file or | 4245 | /* we have to define context: we'll we work with a file or |
| 4247 | * locality group. this is a policy, actually */ | 4246 | * locality group. this is a policy, actually */ |
| @@ -4509,10 +4508,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, | |||
| 4509 | } | 4508 | } |
| 4510 | 4509 | ||
| 4511 | ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS); | 4510 | ac = kmem_cache_alloc(ext4_ac_cachep, GFP_NOFS); |
| 4512 | if (ac) { | 4511 | if (!ac) { |
| 4513 | ac->ac_sb = sb; | ||
| 4514 | ac->ac_inode = ar->inode; | ||
| 4515 | } else { | ||
| 4516 | ar->len = 0; | 4512 | ar->len = 0; |
| 4517 | *errp = -ENOMEM; | 4513 | *errp = -ENOMEM; |
| 4518 | goto out1; | 4514 | goto out1; |
diff --git a/fs/fat/dir.c b/fs/fat/dir.c index 38ff75a0fe22..530b4ca01510 100644 --- a/fs/fat/dir.c +++ b/fs/fat/dir.c | |||
| @@ -16,7 +16,6 @@ | |||
| 16 | #include <linux/module.h> | 16 | #include <linux/module.h> |
| 17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
| 18 | #include <linux/time.h> | 18 | #include <linux/time.h> |
| 19 | #include <linux/smp_lock.h> | ||
| 20 | #include <linux/buffer_head.h> | 19 | #include <linux/buffer_head.h> |
| 21 | #include <linux/compat.h> | 20 | #include <linux/compat.h> |
| 22 | #include <asm/uaccess.h> | 21 | #include <asm/uaccess.h> |
diff --git a/fs/fat/namei_msdos.c b/fs/fat/namei_msdos.c index 82f88733b681..bbc94ae4fd77 100644 --- a/fs/fat/namei_msdos.c +++ b/fs/fat/namei_msdos.c | |||
| @@ -9,7 +9,6 @@ | |||
| 9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
| 10 | #include <linux/time.h> | 10 | #include <linux/time.h> |
| 11 | #include <linux/buffer_head.h> | 11 | #include <linux/buffer_head.h> |
| 12 | #include <linux/smp_lock.h> | ||
| 13 | #include "fat.h" | 12 | #include "fat.h" |
| 14 | 13 | ||
| 15 | /* Characters that are undesirable in an MS-DOS file name */ | 14 | /* Characters that are undesirable in an MS-DOS file name */ |
diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index 73471b7ecc8c..cb6e83557112 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c | |||
| @@ -19,7 +19,6 @@ | |||
| 19 | #include <linux/jiffies.h> | 19 | #include <linux/jiffies.h> |
| 20 | #include <linux/ctype.h> | 20 | #include <linux/ctype.h> |
| 21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
| 22 | #include <linux/smp_lock.h> | ||
| 23 | #include <linux/buffer_head.h> | 22 | #include <linux/buffer_head.h> |
| 24 | #include <linux/namei.h> | 23 | #include <linux/namei.h> |
| 25 | #include "fat.h" | 24 | #include "fat.h" |
diff --git a/fs/fcntl.c b/fs/fcntl.c index a040b764f8e3..ae413086db97 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
| @@ -19,7 +19,6 @@ | |||
| 19 | #include <linux/signal.h> | 19 | #include <linux/signal.h> |
| 20 | #include <linux/rcupdate.h> | 20 | #include <linux/rcupdate.h> |
| 21 | #include <linux/pid_namespace.h> | 21 | #include <linux/pid_namespace.h> |
| 22 | #include <linux/smp_lock.h> | ||
| 23 | 22 | ||
| 24 | #include <asm/poll.h> | 23 | #include <asm/poll.h> |
| 25 | #include <asm/siginfo.h> | 24 | #include <asm/siginfo.h> |
diff --git a/fs/freevxfs/vxfs_super.c b/fs/freevxfs/vxfs_super.c index cdbd1654e4cd..1e8af939b3e4 100644 --- a/fs/freevxfs/vxfs_super.c +++ b/fs/freevxfs/vxfs_super.c | |||
| @@ -38,6 +38,7 @@ | |||
| 38 | #include <linux/buffer_head.h> | 38 | #include <linux/buffer_head.h> |
| 39 | #include <linux/kernel.h> | 39 | #include <linux/kernel.h> |
| 40 | #include <linux/slab.h> | 40 | #include <linux/slab.h> |
| 41 | #include <linux/smp_lock.h> | ||
| 41 | #include <linux/stat.h> | 42 | #include <linux/stat.h> |
| 42 | #include <linux/vfs.h> | 43 | #include <linux/vfs.h> |
| 43 | #include <linux/mount.h> | 44 | #include <linux/mount.h> |
diff --git a/fs/gfs2/trace_gfs2.h b/fs/gfs2/trace_gfs2.h index 98d6ef1c1dc0..148d55c14171 100644 --- a/fs/gfs2/trace_gfs2.h +++ b/fs/gfs2/trace_gfs2.h | |||
| @@ -1,12 +1,11 @@ | |||
| 1 | #undef TRACE_SYSTEM | ||
| 2 | #define TRACE_SYSTEM gfs2 | ||
| 3 | |||
| 1 | #if !defined(_TRACE_GFS2_H) || defined(TRACE_HEADER_MULTI_READ) | 4 | #if !defined(_TRACE_GFS2_H) || defined(TRACE_HEADER_MULTI_READ) |
| 2 | #define _TRACE_GFS2_H | 5 | #define _TRACE_GFS2_H |
| 3 | 6 | ||
| 4 | #include <linux/tracepoint.h> | 7 | #include <linux/tracepoint.h> |
| 5 | 8 | ||
| 6 | #undef TRACE_SYSTEM | ||
| 7 | #define TRACE_SYSTEM gfs2 | ||
| 8 | #define TRACE_INCLUDE_FILE trace_gfs2 | ||
| 9 | |||
| 10 | #include <linux/fs.h> | 9 | #include <linux/fs.h> |
| 11 | #include <linux/buffer_head.h> | 10 | #include <linux/buffer_head.h> |
| 12 | #include <linux/dlmconstants.h> | 11 | #include <linux/dlmconstants.h> |
| @@ -403,5 +402,6 @@ TRACE_EVENT(gfs2_block_alloc, | |||
| 403 | /* This part must be outside protection */ | 402 | /* This part must be outside protection */ |
| 404 | #undef TRACE_INCLUDE_PATH | 403 | #undef TRACE_INCLUDE_PATH |
| 405 | #define TRACE_INCLUDE_PATH . | 404 | #define TRACE_INCLUDE_PATH . |
| 405 | #define TRACE_INCLUDE_FILE trace_gfs2 | ||
| 406 | #include <trace/define_trace.h> | 406 | #include <trace/define_trace.h> |
| 407 | 407 | ||
diff --git a/fs/hfs/super.c b/fs/hfs/super.c index 6f833dc8e910..f7fcbe49da72 100644 --- a/fs/hfs/super.c +++ b/fs/hfs/super.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/nls.h> | 19 | #include <linux/nls.h> |
| 20 | #include <linux/parser.h> | 20 | #include <linux/parser.h> |
| 21 | #include <linux/seq_file.h> | 21 | #include <linux/seq_file.h> |
| 22 | #include <linux/smp_lock.h> | ||
| 22 | #include <linux/vfs.h> | 23 | #include <linux/vfs.h> |
| 23 | 24 | ||
| 24 | #include "hfs_fs.h" | 25 | #include "hfs_fs.h" |
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index 9fc3af0c0dab..c0759fe0855b 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <linux/pagemap.h> | 12 | #include <linux/pagemap.h> |
| 13 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
| 14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
| 15 | #include <linux/smp_lock.h> | ||
| 15 | #include <linux/vfs.h> | 16 | #include <linux/vfs.h> |
| 16 | #include <linux/nls.h> | 17 | #include <linux/nls.h> |
| 17 | 18 | ||
diff --git a/fs/hpfs/dir.c b/fs/hpfs/dir.c index 6916c41d7017..8865c94f55f6 100644 --- a/fs/hpfs/dir.c +++ b/fs/hpfs/dir.c | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | * directory VFS functions | 6 | * directory VFS functions |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <linux/smp_lock.h> | ||
| 9 | #include "hpfs_fn.h" | 10 | #include "hpfs_fn.h" |
| 10 | 11 | ||
| 11 | static int hpfs_dir_release(struct inode *inode, struct file *filp) | 12 | static int hpfs_dir_release(struct inode *inode, struct file *filp) |
diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c index 64ab52259204..3efabff00367 100644 --- a/fs/hpfs/file.c +++ b/fs/hpfs/file.c | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | * file VFS functions | 6 | * file VFS functions |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <linux/smp_lock.h> | ||
| 9 | #include "hpfs_fn.h" | 10 | #include "hpfs_fn.h" |
| 10 | 11 | ||
| 11 | #define BLOCKS(size) (((size) + 511) >> 9) | 12 | #define BLOCKS(size) (((size) + 511) >> 9) |
diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h index c2ea31bae313..701ca54c0867 100644 --- a/fs/hpfs/hpfs_fn.h +++ b/fs/hpfs/hpfs_fn.h | |||
| @@ -13,7 +13,6 @@ | |||
| 13 | #include <linux/pagemap.h> | 13 | #include <linux/pagemap.h> |
| 14 | #include <linux/buffer_head.h> | 14 | #include <linux/buffer_head.h> |
| 15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
| 16 | #include <linux/smp_lock.h> | ||
| 17 | 16 | ||
| 18 | #include "hpfs.h" | 17 | #include "hpfs.h" |
| 19 | 18 | ||
diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c index 39a1bfbea312..fe703ae46bc7 100644 --- a/fs/hpfs/inode.c +++ b/fs/hpfs/inode.c | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | * inode VFS functions | 6 | * inode VFS functions |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <linux/smp_lock.h> | ||
| 9 | #include "hpfs_fn.h" | 10 | #include "hpfs_fn.h" |
| 10 | 11 | ||
| 11 | void hpfs_init_inode(struct inode *i) | 12 | void hpfs_init_inode(struct inode *i) |
diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c index b649232dde97..82b9c4ba9ed0 100644 --- a/fs/hpfs/namei.c +++ b/fs/hpfs/namei.c | |||
| @@ -6,6 +6,7 @@ | |||
| 6 | * adding & removing files & directories | 6 | * adding & removing files & directories |
| 7 | */ | 7 | */ |
| 8 | #include <linux/sched.h> | 8 | #include <linux/sched.h> |
| 9 | #include <linux/smp_lock.h> | ||
| 9 | #include "hpfs_fn.h" | 10 | #include "hpfs_fn.h" |
| 10 | 11 | ||
| 11 | static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) | 12 | static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) |
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c index 58a7963e168a..85f96bc651c7 100644 --- a/fs/isofs/inode.c +++ b/fs/isofs/inode.c | |||
| @@ -142,6 +142,7 @@ static const struct dentry_operations isofs_dentry_ops[] = { | |||
| 142 | 142 | ||
| 143 | struct iso9660_options{ | 143 | struct iso9660_options{ |
| 144 | unsigned int rock:1; | 144 | unsigned int rock:1; |
| 145 | unsigned int joliet:1; | ||
| 145 | unsigned int cruft:1; | 146 | unsigned int cruft:1; |
| 146 | unsigned int hide:1; | 147 | unsigned int hide:1; |
| 147 | unsigned int showassoc:1; | 148 | unsigned int showassoc:1; |
| @@ -151,7 +152,6 @@ struct iso9660_options{ | |||
| 151 | unsigned int gid_set:1; | 152 | unsigned int gid_set:1; |
| 152 | unsigned int utf8:1; | 153 | unsigned int utf8:1; |
| 153 | unsigned char map; | 154 | unsigned char map; |
| 154 | char joliet; | ||
| 155 | unsigned char check; | 155 | unsigned char check; |
| 156 | unsigned int blocksize; | 156 | unsigned int blocksize; |
| 157 | mode_t fmode; | 157 | mode_t fmode; |
| @@ -632,7 +632,7 @@ static int isofs_fill_super(struct super_block *s, void *data, int silent) | |||
| 632 | else if (isonum_711(vdp->type) == ISO_VD_SUPPLEMENTARY) { | 632 | else if (isonum_711(vdp->type) == ISO_VD_SUPPLEMENTARY) { |
| 633 | sec = (struct iso_supplementary_descriptor *)vdp; | 633 | sec = (struct iso_supplementary_descriptor *)vdp; |
| 634 | if (sec->escape[0] == 0x25 && sec->escape[1] == 0x2f) { | 634 | if (sec->escape[0] == 0x25 && sec->escape[1] == 0x2f) { |
| 635 | if (opt.joliet == 'y') { | 635 | if (opt.joliet) { |
| 636 | if (sec->escape[2] == 0x40) | 636 | if (sec->escape[2] == 0x40) |
| 637 | joliet_level = 1; | 637 | joliet_level = 1; |
| 638 | else if (sec->escape[2] == 0x43) | 638 | else if (sec->escape[2] == 0x43) |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 18bfd5dab642..e378cb383979 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
| @@ -297,6 +297,7 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction, | |||
| 297 | unsigned int new_offset; | 297 | unsigned int new_offset; |
| 298 | struct buffer_head *bh_in = jh2bh(jh_in); | 298 | struct buffer_head *bh_in = jh2bh(jh_in); |
| 299 | struct jbd2_buffer_trigger_type *triggers; | 299 | struct jbd2_buffer_trigger_type *triggers; |
| 300 | journal_t *journal = transaction->t_journal; | ||
| 300 | 301 | ||
| 301 | /* | 302 | /* |
| 302 | * The buffer really shouldn't be locked: only the current committing | 303 | * The buffer really shouldn't be locked: only the current committing |
| @@ -310,6 +311,11 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction, | |||
| 310 | J_ASSERT_BH(bh_in, buffer_jbddirty(bh_in)); | 311 | J_ASSERT_BH(bh_in, buffer_jbddirty(bh_in)); |
| 311 | 312 | ||
| 312 | new_bh = alloc_buffer_head(GFP_NOFS|__GFP_NOFAIL); | 313 | new_bh = alloc_buffer_head(GFP_NOFS|__GFP_NOFAIL); |
| 314 | /* keep subsequent assertions sane */ | ||
| 315 | new_bh->b_state = 0; | ||
| 316 | init_buffer(new_bh, NULL, NULL); | ||
| 317 | atomic_set(&new_bh->b_count, 1); | ||
| 318 | new_jh = jbd2_journal_add_journal_head(new_bh); /* This sleeps */ | ||
| 313 | 319 | ||
| 314 | /* | 320 | /* |
| 315 | * If a new transaction has already done a buffer copy-out, then | 321 | * If a new transaction has already done a buffer copy-out, then |
| @@ -388,14 +394,6 @@ repeat: | |||
| 388 | kunmap_atomic(mapped_data, KM_USER0); | 394 | kunmap_atomic(mapped_data, KM_USER0); |
| 389 | } | 395 | } |
| 390 | 396 | ||
| 391 | /* keep subsequent assertions sane */ | ||
| 392 | new_bh->b_state = 0; | ||
| 393 | init_buffer(new_bh, NULL, NULL); | ||
| 394 | atomic_set(&new_bh->b_count, 1); | ||
| 395 | jbd_unlock_bh_state(bh_in); | ||
| 396 | |||
| 397 | new_jh = jbd2_journal_add_journal_head(new_bh); /* This sleeps */ | ||
| 398 | |||
| 399 | set_bh_page(new_bh, new_page, new_offset); | 397 | set_bh_page(new_bh, new_page, new_offset); |
| 400 | new_jh->b_transaction = NULL; | 398 | new_jh->b_transaction = NULL; |
| 401 | new_bh->b_size = jh2bh(jh_in)->b_size; | 399 | new_bh->b_size = jh2bh(jh_in)->b_size; |
| @@ -412,7 +410,11 @@ repeat: | |||
| 412 | * copying is moved to the transaction's shadow queue. | 410 | * copying is moved to the transaction's shadow queue. |
| 413 | */ | 411 | */ |
| 414 | JBUFFER_TRACE(jh_in, "file as BJ_Shadow"); | 412 | JBUFFER_TRACE(jh_in, "file as BJ_Shadow"); |
| 415 | jbd2_journal_file_buffer(jh_in, transaction, BJ_Shadow); | 413 | spin_lock(&journal->j_list_lock); |
| 414 | __jbd2_journal_file_buffer(jh_in, transaction, BJ_Shadow); | ||
| 415 | spin_unlock(&journal->j_list_lock); | ||
| 416 | jbd_unlock_bh_state(bh_in); | ||
| 417 | |||
| 416 | JBUFFER_TRACE(new_jh, "file as BJ_IO"); | 418 | JBUFFER_TRACE(new_jh, "file as BJ_IO"); |
| 417 | jbd2_journal_file_buffer(new_jh, transaction, BJ_IO); | 419 | jbd2_journal_file_buffer(new_jh, transaction, BJ_IO); |
| 418 | 420 | ||
| @@ -2410,6 +2412,7 @@ const char *jbd2_dev_to_name(dev_t device) | |||
| 2410 | int i = hash_32(device, CACHE_SIZE_BITS); | 2412 | int i = hash_32(device, CACHE_SIZE_BITS); |
| 2411 | char *ret; | 2413 | char *ret; |
| 2412 | struct block_device *bd; | 2414 | struct block_device *bd; |
| 2415 | static struct devname_cache *new_dev; | ||
| 2413 | 2416 | ||
| 2414 | rcu_read_lock(); | 2417 | rcu_read_lock(); |
| 2415 | if (devcache[i] && devcache[i]->device == device) { | 2418 | if (devcache[i] && devcache[i]->device == device) { |
| @@ -2419,20 +2422,20 @@ const char *jbd2_dev_to_name(dev_t device) | |||
| 2419 | } | 2422 | } |
| 2420 | rcu_read_unlock(); | 2423 | rcu_read_unlock(); |
| 2421 | 2424 | ||
| 2425 | new_dev = kmalloc(sizeof(struct devname_cache), GFP_KERNEL); | ||
| 2426 | if (!new_dev) | ||
| 2427 | return "NODEV-ALLOCFAILURE"; /* Something non-NULL */ | ||
| 2422 | spin_lock(&devname_cache_lock); | 2428 | spin_lock(&devname_cache_lock); |
| 2423 | if (devcache[i]) { | 2429 | if (devcache[i]) { |
| 2424 | if (devcache[i]->device == device) { | 2430 | if (devcache[i]->device == device) { |
| 2431 | kfree(new_dev); | ||
| 2425 | ret = devcache[i]->devname; | 2432 | ret = devcache[i]->devname; |
| 2426 | spin_unlock(&devname_cache_lock); | 2433 | spin_unlock(&devname_cache_lock); |
| 2427 | return ret; | 2434 | return ret; |
| 2428 | } | 2435 | } |
| 2429 | call_rcu(&devcache[i]->rcu, free_devcache); | 2436 | call_rcu(&devcache[i]->rcu, free_devcache); |
| 2430 | } | 2437 | } |
| 2431 | devcache[i] = kmalloc(sizeof(struct devname_cache), GFP_KERNEL); | 2438 | devcache[i] = new_dev; |
| 2432 | if (!devcache[i]) { | ||
| 2433 | spin_unlock(&devname_cache_lock); | ||
| 2434 | return "NODEV-ALLOCFAILURE"; /* Something non-NULL */ | ||
| 2435 | } | ||
| 2436 | devcache[i]->device = device; | 2439 | devcache[i]->device = device; |
| 2437 | bd = bdget(device); | 2440 | bd = bdget(device); |
| 2438 | if (bd) { | 2441 | if (bd) { |
diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 494501edba6b..6213ac728f30 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c | |||
| @@ -499,34 +499,15 @@ void jbd2_journal_unlock_updates (journal_t *journal) | |||
| 499 | wake_up(&journal->j_wait_transaction_locked); | 499 | wake_up(&journal->j_wait_transaction_locked); |
| 500 | } | 500 | } |
| 501 | 501 | ||
| 502 | /* | 502 | static void warn_dirty_buffer(struct buffer_head *bh) |
| 503 | * Report any unexpected dirty buffers which turn up. Normally those | ||
| 504 | * indicate an error, but they can occur if the user is running (say) | ||
| 505 | * tune2fs to modify the live filesystem, so we need the option of | ||
| 506 | * continuing as gracefully as possible. # | ||
| 507 | * | ||
| 508 | * The caller should already hold the journal lock and | ||
| 509 | * j_list_lock spinlock: most callers will need those anyway | ||
| 510 | * in order to probe the buffer's journaling state safely. | ||
| 511 | */ | ||
| 512 | static void jbd_unexpected_dirty_buffer(struct journal_head *jh) | ||
| 513 | { | 503 | { |
| 514 | int jlist; | 504 | char b[BDEVNAME_SIZE]; |
| 515 | |||
| 516 | /* If this buffer is one which might reasonably be dirty | ||
| 517 | * --- ie. data, or not part of this journal --- then | ||
| 518 | * we're OK to leave it alone, but otherwise we need to | ||
| 519 | * move the dirty bit to the journal's own internal | ||
| 520 | * JBDDirty bit. */ | ||
| 521 | jlist = jh->b_jlist; | ||
| 522 | 505 | ||
| 523 | if (jlist == BJ_Metadata || jlist == BJ_Reserved || | 506 | printk(KERN_WARNING |
| 524 | jlist == BJ_Shadow || jlist == BJ_Forget) { | 507 | "JBD: Spotted dirty metadata buffer (dev = %s, blocknr = %llu). " |
| 525 | struct buffer_head *bh = jh2bh(jh); | 508 | "There's a risk of filesystem corruption in case of system " |
| 526 | 509 | "crash.\n", | |
| 527 | if (test_clear_buffer_dirty(bh)) | 510 | bdevname(bh->b_bdev, b), (unsigned long long)bh->b_blocknr); |
| 528 | set_buffer_jbddirty(bh); | ||
| 529 | } | ||
| 530 | } | 511 | } |
| 531 | 512 | ||
| 532 | /* | 513 | /* |
| @@ -593,14 +574,16 @@ repeat: | |||
| 593 | if (jh->b_next_transaction) | 574 | if (jh->b_next_transaction) |
| 594 | J_ASSERT_JH(jh, jh->b_next_transaction == | 575 | J_ASSERT_JH(jh, jh->b_next_transaction == |
| 595 | transaction); | 576 | transaction); |
| 577 | warn_dirty_buffer(bh); | ||
| 596 | } | 578 | } |
| 597 | /* | 579 | /* |
| 598 | * In any case we need to clean the dirty flag and we must | 580 | * In any case we need to clean the dirty flag and we must |
| 599 | * do it under the buffer lock to be sure we don't race | 581 | * do it under the buffer lock to be sure we don't race |
| 600 | * with running write-out. | 582 | * with running write-out. |
| 601 | */ | 583 | */ |
| 602 | JBUFFER_TRACE(jh, "Unexpected dirty buffer"); | 584 | JBUFFER_TRACE(jh, "Journalling dirty buffer"); |
| 603 | jbd_unexpected_dirty_buffer(jh); | 585 | clear_buffer_dirty(bh); |
| 586 | set_buffer_jbddirty(bh); | ||
| 604 | } | 587 | } |
| 605 | 588 | ||
| 606 | unlock_buffer(bh); | 589 | unlock_buffer(bh); |
| @@ -843,6 +826,15 @@ int jbd2_journal_get_create_access(handle_t *handle, struct buffer_head *bh) | |||
| 843 | J_ASSERT_JH(jh, buffer_locked(jh2bh(jh))); | 826 | J_ASSERT_JH(jh, buffer_locked(jh2bh(jh))); |
| 844 | 827 | ||
| 845 | if (jh->b_transaction == NULL) { | 828 | if (jh->b_transaction == NULL) { |
| 829 | /* | ||
| 830 | * Previous jbd2_journal_forget() could have left the buffer | ||
| 831 | * with jbddirty bit set because it was being committed. When | ||
| 832 | * the commit finished, we've filed the buffer for | ||
| 833 | * checkpointing and marked it dirty. Now we are reallocating | ||
| 834 | * the buffer so the transaction freeing it must have | ||
| 835 | * committed and so it's safe to clear the dirty bit. | ||
| 836 | */ | ||
| 837 | clear_buffer_dirty(jh2bh(jh)); | ||
| 846 | jh->b_transaction = transaction; | 838 | jh->b_transaction = transaction; |
| 847 | 839 | ||
| 848 | /* first access by this transaction */ | 840 | /* first access by this transaction */ |
| @@ -1644,8 +1636,13 @@ static int __dispose_buffer(struct journal_head *jh, transaction_t *transaction) | |||
| 1644 | 1636 | ||
| 1645 | if (jh->b_cp_transaction) { | 1637 | if (jh->b_cp_transaction) { |
| 1646 | JBUFFER_TRACE(jh, "on running+cp transaction"); | 1638 | JBUFFER_TRACE(jh, "on running+cp transaction"); |
| 1639 | /* | ||
| 1640 | * We don't want to write the buffer anymore, clear the | ||
| 1641 | * bit so that we don't confuse checks in | ||
| 1642 | * __journal_file_buffer | ||
| 1643 | */ | ||
| 1644 | clear_buffer_dirty(bh); | ||
| 1647 | __jbd2_journal_file_buffer(jh, transaction, BJ_Forget); | 1645 | __jbd2_journal_file_buffer(jh, transaction, BJ_Forget); |
| 1648 | clear_buffer_jbddirty(bh); | ||
| 1649 | may_free = 0; | 1646 | may_free = 0; |
| 1650 | } else { | 1647 | } else { |
| 1651 | JBUFFER_TRACE(jh, "on running transaction"); | 1648 | JBUFFER_TRACE(jh, "on running transaction"); |
| @@ -1896,12 +1893,17 @@ void __jbd2_journal_file_buffer(struct journal_head *jh, | |||
| 1896 | if (jh->b_transaction && jh->b_jlist == jlist) | 1893 | if (jh->b_transaction && jh->b_jlist == jlist) |
| 1897 | return; | 1894 | return; |
| 1898 | 1895 | ||
| 1899 | /* The following list of buffer states needs to be consistent | ||
| 1900 | * with __jbd_unexpected_dirty_buffer()'s handling of dirty | ||
| 1901 | * state. */ | ||
| 1902 | |||
| 1903 | if (jlist == BJ_Metadata || jlist == BJ_Reserved || | 1896 | if (jlist == BJ_Metadata || jlist == BJ_Reserved || |
| 1904 | jlist == BJ_Shadow || jlist == BJ_Forget) { | 1897 | jlist == BJ_Shadow || jlist == BJ_Forget) { |
| 1898 | /* | ||
| 1899 | * For metadata buffers, we track dirty bit in buffer_jbddirty | ||
| 1900 | * instead of buffer_dirty. We should not see a dirty bit set | ||
| 1901 | * here because we clear it in do_get_write_access but e.g. | ||
| 1902 | * tune2fs can modify the sb and set the dirty bit at any time | ||
| 1903 | * so we try to gracefully handle that. | ||
| 1904 | */ | ||
| 1905 | if (buffer_dirty(bh)) | ||
| 1906 | warn_dirty_buffer(bh); | ||
| 1905 | if (test_clear_buffer_dirty(bh) || | 1907 | if (test_clear_buffer_dirty(bh) || |
| 1906 | test_clear_buffer_jbddirty(bh)) | 1908 | test_clear_buffer_jbddirty(bh)) |
| 1907 | was_dirty = 1; | 1909 | was_dirty = 1; |
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c index 07a22caf2687..0035c021395a 100644 --- a/fs/jffs2/super.c +++ b/fs/jffs2/super.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
| 13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
| 14 | #include <linux/slab.h> | 14 | #include <linux/slab.h> |
| 15 | #include <linux/smp_lock.h> | ||
| 15 | #include <linux/init.h> | 16 | #include <linux/init.h> |
| 16 | #include <linux/list.h> | 17 | #include <linux/list.h> |
| 17 | #include <linux/fs.h> | 18 | #include <linux/fs.h> |
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index f2fdcbce143e..4336adba952a 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include <linux/module.h> | 9 | #include <linux/module.h> |
| 10 | #include <linux/smp_lock.h> | ||
| 10 | #include <linux/types.h> | 11 | #include <linux/types.h> |
| 11 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
| 12 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index 1725037374c5..bd173a6ca3b1 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include <linux/types.h> | 10 | #include <linux/types.h> |
| 11 | #include <linux/time.h> | 11 | #include <linux/time.h> |
| 12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
| 13 | #include <linux/smp_lock.h> | ||
| 13 | #include <linux/in.h> | 14 | #include <linux/in.h> |
| 14 | #include <linux/sunrpc/svc.h> | 15 | #include <linux/sunrpc/svc.h> |
| 15 | #include <linux/sunrpc/clnt.h> | 16 | #include <linux/sunrpc/clnt.h> |
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 3688e55901fc..e1d28ddd2169 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include <linux/types.h> | 10 | #include <linux/types.h> |
| 11 | #include <linux/time.h> | 11 | #include <linux/time.h> |
| 12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
| 13 | #include <linux/smp_lock.h> | ||
| 13 | #include <linux/in.h> | 14 | #include <linux/in.h> |
| 14 | #include <linux/sunrpc/svc.h> | 15 | #include <linux/sunrpc/svc.h> |
| 15 | #include <linux/sunrpc/clnt.h> | 16 | #include <linux/sunrpc/clnt.h> |
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index c2d061675d80..8d25ccb2d51d 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
| @@ -1242,20 +1242,6 @@ error: | |||
| 1242 | return error; | 1242 | return error; |
| 1243 | } | 1243 | } |
| 1244 | 1244 | ||
| 1245 | /* | ||
| 1246 | * Initialize a session. | ||
| 1247 | * Note: save the mount rsize and wsize for create_server negotiation. | ||
| 1248 | */ | ||
| 1249 | static void nfs4_init_session(struct nfs_client *clp, | ||
| 1250 | unsigned int wsize, unsigned int rsize) | ||
| 1251 | { | ||
| 1252 | #if defined(CONFIG_NFS_V4_1) | ||
| 1253 | if (nfs4_has_session(clp)) { | ||
| 1254 | clp->cl_session->fc_attrs.max_rqst_sz = wsize; | ||
| 1255 | clp->cl_session->fc_attrs.max_resp_sz = rsize; | ||
| 1256 | } | ||
| 1257 | #endif /* CONFIG_NFS_V4_1 */ | ||
| 1258 | } | ||
| 1259 | 1245 | ||
| 1260 | /* | 1246 | /* |
| 1261 | * Session has been established, and the client marked ready. | 1247 | * Session has been established, and the client marked ready. |
| @@ -1350,7 +1336,9 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data, | |||
| 1350 | BUG_ON(!server->nfs_client->rpc_ops); | 1336 | BUG_ON(!server->nfs_client->rpc_ops); |
| 1351 | BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); | 1337 | BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); |
| 1352 | 1338 | ||
| 1353 | nfs4_init_session(server->nfs_client, server->wsize, server->rsize); | 1339 | error = nfs4_init_session(server); |
| 1340 | if (error < 0) | ||
| 1341 | goto error; | ||
| 1354 | 1342 | ||
| 1355 | /* Probe the root fh to retrieve its FSID */ | 1343 | /* Probe the root fh to retrieve its FSID */ |
| 1356 | error = nfs4_path_walk(server, mntfh, data->nfs_server.export_path); | 1344 | error = nfs4_path_walk(server, mntfh, data->nfs_server.export_path); |
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index af05b918cb5b..6dd48a4405b4 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | #include <linux/kthread.h> | 10 | #include <linux/kthread.h> |
| 11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
| 12 | #include <linux/sched.h> | 12 | #include <linux/sched.h> |
| 13 | #include <linux/smp_lock.h> | ||
| 13 | #include <linux/spinlock.h> | 14 | #include <linux/spinlock.h> |
| 14 | 15 | ||
| 15 | #include <linux/nfs4.h> | 16 | #include <linux/nfs4.h> |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 89f98e9a024b..32062c33c859 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
| @@ -29,7 +29,6 @@ | |||
| 29 | #include <linux/nfs_fs.h> | 29 | #include <linux/nfs_fs.h> |
| 30 | #include <linux/nfs_mount.h> | 30 | #include <linux/nfs_mount.h> |
| 31 | #include <linux/pagemap.h> | 31 | #include <linux/pagemap.h> |
| 32 | #include <linux/smp_lock.h> | ||
| 33 | #include <linux/pagevec.h> | 32 | #include <linux/pagevec.h> |
| 34 | #include <linux/namei.h> | 33 | #include <linux/namei.h> |
| 35 | #include <linux/mount.h> | 34 | #include <linux/mount.h> |
| @@ -1026,12 +1025,12 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry | |||
| 1026 | res = NULL; | 1025 | res = NULL; |
| 1027 | goto out; | 1026 | goto out; |
| 1028 | /* This turned out not to be a regular file */ | 1027 | /* This turned out not to be a regular file */ |
| 1029 | case -EISDIR: | ||
| 1030 | case -ENOTDIR: | 1028 | case -ENOTDIR: |
| 1031 | goto no_open; | 1029 | goto no_open; |
| 1032 | case -ELOOP: | 1030 | case -ELOOP: |
| 1033 | if (!(nd->intent.open.flags & O_NOFOLLOW)) | 1031 | if (!(nd->intent.open.flags & O_NOFOLLOW)) |
| 1034 | goto no_open; | 1032 | goto no_open; |
| 1033 | /* case -EISDIR: */ | ||
| 1035 | /* case -EINVAL: */ | 1034 | /* case -EINVAL: */ |
| 1036 | default: | 1035 | default: |
| 1037 | goto out; | 1036 | goto out; |
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index 0055b813ec2c..05062329b678 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
| @@ -26,7 +26,6 @@ | |||
| 26 | #include <linux/mm.h> | 26 | #include <linux/mm.h> |
| 27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
| 28 | #include <linux/pagemap.h> | 28 | #include <linux/pagemap.h> |
| 29 | #include <linux/smp_lock.h> | ||
| 30 | #include <linux/aio.h> | 29 | #include <linux/aio.h> |
| 31 | 30 | ||
| 32 | #include <asm/uaccess.h> | 31 | #include <asm/uaccess.h> |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 64f87194d390..bd7938eda6a8 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
| @@ -30,7 +30,6 @@ | |||
| 30 | #include <linux/nfs_mount.h> | 30 | #include <linux/nfs_mount.h> |
| 31 | #include <linux/nfs4_mount.h> | 31 | #include <linux/nfs4_mount.h> |
| 32 | #include <linux/lockd/bind.h> | 32 | #include <linux/lockd/bind.h> |
| 33 | #include <linux/smp_lock.h> | ||
| 34 | #include <linux/seq_file.h> | 33 | #include <linux/seq_file.h> |
| 35 | #include <linux/mount.h> | 34 | #include <linux/mount.h> |
| 36 | #include <linux/nfs_idmap.h> | 35 | #include <linux/nfs_idmap.h> |
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 61bc3a32e1e2..6ea07a3c75d4 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h | |||
| @@ -220,6 +220,7 @@ extern void nfs4_destroy_session(struct nfs4_session *session); | |||
| 220 | extern struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp); | 220 | extern struct nfs4_session *nfs4_alloc_session(struct nfs_client *clp); |
| 221 | extern int nfs4_proc_create_session(struct nfs_client *, int reset); | 221 | extern int nfs4_proc_create_session(struct nfs_client *, int reset); |
| 222 | extern int nfs4_proc_destroy_session(struct nfs4_session *); | 222 | extern int nfs4_proc_destroy_session(struct nfs4_session *); |
| 223 | extern int nfs4_init_session(struct nfs_server *server); | ||
| 223 | #else /* CONFIG_NFS_v4_1 */ | 224 | #else /* CONFIG_NFS_v4_1 */ |
| 224 | static inline int nfs4_setup_sequence(struct nfs_client *clp, | 225 | static inline int nfs4_setup_sequence(struct nfs_client *clp, |
| 225 | struct nfs4_sequence_args *args, struct nfs4_sequence_res *res, | 226 | struct nfs4_sequence_args *args, struct nfs4_sequence_res *res, |
| @@ -227,6 +228,11 @@ static inline int nfs4_setup_sequence(struct nfs_client *clp, | |||
| 227 | { | 228 | { |
| 228 | return 0; | 229 | return 0; |
| 229 | } | 230 | } |
| 231 | |||
| 232 | static inline int nfs4_init_session(struct nfs_server *server) | ||
| 233 | { | ||
| 234 | return 0; | ||
| 235 | } | ||
| 230 | #endif /* CONFIG_NFS_V4_1 */ | 236 | #endif /* CONFIG_NFS_V4_1 */ |
| 231 | 237 | ||
| 232 | extern struct nfs4_state_maintenance_ops *nfs4_state_renewal_ops[]; | 238 | extern struct nfs4_state_maintenance_ops *nfs4_state_renewal_ops[]; |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 92ce43517814..6917311f201c 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
| @@ -45,7 +45,6 @@ | |||
| 45 | #include <linux/nfs4.h> | 45 | #include <linux/nfs4.h> |
| 46 | #include <linux/nfs_fs.h> | 46 | #include <linux/nfs_fs.h> |
| 47 | #include <linux/nfs_page.h> | 47 | #include <linux/nfs_page.h> |
| 48 | #include <linux/smp_lock.h> | ||
| 49 | #include <linux/namei.h> | 48 | #include <linux/namei.h> |
| 50 | #include <linux/mount.h> | 49 | #include <linux/mount.h> |
| 51 | #include <linux/module.h> | 50 | #include <linux/module.h> |
| @@ -2041,15 +2040,9 @@ static int _nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle, | |||
| 2041 | .rpc_argp = &args, | 2040 | .rpc_argp = &args, |
| 2042 | .rpc_resp = &res, | 2041 | .rpc_resp = &res, |
| 2043 | }; | 2042 | }; |
| 2044 | int status; | ||
| 2045 | 2043 | ||
| 2046 | nfs_fattr_init(info->fattr); | 2044 | nfs_fattr_init(info->fattr); |
| 2047 | status = nfs4_recover_expired_lease(server); | 2045 | return nfs4_call_sync(server, &msg, &args, &res, 0); |
| 2048 | if (!status) | ||
| 2049 | status = nfs4_check_client_ready(server->nfs_client); | ||
| 2050 | if (!status) | ||
| 2051 | status = nfs4_call_sync(server, &msg, &args, &res, 0); | ||
| 2052 | return status; | ||
| 2053 | } | 2046 | } |
| 2054 | 2047 | ||
| 2055 | static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle, | 2048 | static int nfs4_lookup_root(struct nfs_server *server, struct nfs_fh *fhandle, |
| @@ -4100,15 +4093,23 @@ nfs4_proc_lock(struct file *filp, int cmd, struct file_lock *request) | |||
| 4100 | if (request->fl_start < 0 || request->fl_end < 0) | 4093 | if (request->fl_start < 0 || request->fl_end < 0) |
| 4101 | return -EINVAL; | 4094 | return -EINVAL; |
| 4102 | 4095 | ||
| 4103 | if (IS_GETLK(cmd)) | 4096 | if (IS_GETLK(cmd)) { |
| 4104 | return nfs4_proc_getlk(state, F_GETLK, request); | 4097 | if (state != NULL) |
| 4098 | return nfs4_proc_getlk(state, F_GETLK, request); | ||
| 4099 | return 0; | ||
| 4100 | } | ||
| 4105 | 4101 | ||
| 4106 | if (!(IS_SETLK(cmd) || IS_SETLKW(cmd))) | 4102 | if (!(IS_SETLK(cmd) || IS_SETLKW(cmd))) |
| 4107 | return -EINVAL; | 4103 | return -EINVAL; |
| 4108 | 4104 | ||
| 4109 | if (request->fl_type == F_UNLCK) | 4105 | if (request->fl_type == F_UNLCK) { |
| 4110 | return nfs4_proc_unlck(state, cmd, request); | 4106 | if (state != NULL) |
| 4107 | return nfs4_proc_unlck(state, cmd, request); | ||
| 4108 | return 0; | ||
| 4109 | } | ||
| 4111 | 4110 | ||
| 4111 | if (state == NULL) | ||
| 4112 | return -ENOLCK; | ||
| 4112 | do { | 4113 | do { |
| 4113 | status = nfs4_proc_setlk(state, cmd, request); | 4114 | status = nfs4_proc_setlk(state, cmd, request); |
| 4114 | if ((status != -EAGAIN) || IS_SETLK(cmd)) | 4115 | if ((status != -EAGAIN) || IS_SETLK(cmd)) |
| @@ -4794,6 +4795,22 @@ int nfs4_proc_destroy_session(struct nfs4_session *session) | |||
| 4794 | return status; | 4795 | return status; |
| 4795 | } | 4796 | } |
| 4796 | 4797 | ||
| 4798 | int nfs4_init_session(struct nfs_server *server) | ||
| 4799 | { | ||
| 4800 | struct nfs_client *clp = server->nfs_client; | ||
| 4801 | int ret; | ||
| 4802 | |||
| 4803 | if (!nfs4_has_session(clp)) | ||
| 4804 | return 0; | ||
| 4805 | |||
| 4806 | clp->cl_session->fc_attrs.max_rqst_sz = server->wsize; | ||
| 4807 | clp->cl_session->fc_attrs.max_resp_sz = server->rsize; | ||
| 4808 | ret = nfs4_recover_expired_lease(server); | ||
| 4809 | if (!ret) | ||
| 4810 | ret = nfs4_check_client_ready(clp); | ||
| 4811 | return ret; | ||
| 4812 | } | ||
| 4813 | |||
| 4797 | /* | 4814 | /* |
| 4798 | * Renew the cl_session lease. | 4815 | * Renew the cl_session lease. |
| 4799 | */ | 4816 | */ |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index b73c5a728655..65ca8c18476f 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
| @@ -553,6 +553,7 @@ static struct nfs4_lock_state *nfs4_alloc_lock_state(struct nfs4_state *state, f | |||
| 553 | INIT_LIST_HEAD(&lsp->ls_sequence.list); | 553 | INIT_LIST_HEAD(&lsp->ls_sequence.list); |
| 554 | lsp->ls_seqid.sequence = &lsp->ls_sequence; | 554 | lsp->ls_seqid.sequence = &lsp->ls_sequence; |
| 555 | atomic_set(&lsp->ls_count, 1); | 555 | atomic_set(&lsp->ls_count, 1); |
| 556 | lsp->ls_state = state; | ||
| 556 | lsp->ls_owner = fl_owner; | 557 | lsp->ls_owner = fl_owner; |
| 557 | spin_lock(&clp->cl_lock); | 558 | spin_lock(&clp->cl_lock); |
| 558 | nfs_alloc_unique_id(&clp->cl_lockowner_id, &lsp->ls_id, 1, 64); | 559 | nfs_alloc_unique_id(&clp->cl_lockowner_id, &lsp->ls_id, 1, 64); |
| @@ -587,7 +588,6 @@ static struct nfs4_lock_state *nfs4_get_lock_state(struct nfs4_state *state, fl_ | |||
| 587 | if (lsp != NULL) | 588 | if (lsp != NULL) |
| 588 | break; | 589 | break; |
| 589 | if (new != NULL) { | 590 | if (new != NULL) { |
| 590 | new->ls_state = state; | ||
| 591 | list_add(&new->ls_locks, &state->lock_states); | 591 | list_add(&new->ls_locks, &state->lock_states); |
| 592 | set_bit(LK_STATE_IN_USE, &state->flags); | 592 | set_bit(LK_STATE_IN_USE, &state->flags); |
| 593 | lsp = new; | 593 | lsp = new; |
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 96c4ebfa46f4..73ea5e8d66ce 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
| @@ -18,7 +18,6 @@ | |||
| 18 | #include <linux/sunrpc/clnt.h> | 18 | #include <linux/sunrpc/clnt.h> |
| 19 | #include <linux/nfs_fs.h> | 19 | #include <linux/nfs_fs.h> |
| 20 | #include <linux/nfs_page.h> | 20 | #include <linux/nfs_page.h> |
| 21 | #include <linux/smp_lock.h> | ||
| 22 | 21 | ||
| 23 | #include <asm/system.h> | 22 | #include <asm/system.h> |
| 24 | 23 | ||
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 1250fb978ac1..6d0847562d87 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c | |||
| @@ -25,7 +25,6 @@ | |||
| 25 | #include <linux/init.h> | 25 | #include <linux/init.h> |
| 26 | #include <linux/inet.h> | 26 | #include <linux/inet.h> |
| 27 | #include <linux/string.h> | 27 | #include <linux/string.h> |
| 28 | #include <linux/smp_lock.h> | ||
| 29 | #include <linux/ctype.h> | 28 | #include <linux/ctype.h> |
| 30 | 29 | ||
| 31 | #include <linux/nfs.h> | 30 | #include <linux/nfs.h> |
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index d4c9884cd54b..492c79b7800b 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c | |||
| @@ -18,7 +18,6 @@ | |||
| 18 | #include <linux/unistd.h> | 18 | #include <linux/unistd.h> |
| 19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
| 20 | #include <linux/smp.h> | 20 | #include <linux/smp.h> |
| 21 | #include <linux/smp_lock.h> | ||
| 22 | #include <linux/freezer.h> | 21 | #include <linux/freezer.h> |
| 23 | #include <linux/fs_struct.h> | 22 | #include <linux/fs_struct.h> |
| 24 | #include <linux/kthread.h> | 23 | #include <linux/kthread.h> |
diff --git a/fs/nilfs2/Kconfig b/fs/nilfs2/Kconfig new file mode 100644 index 000000000000..72da095d4009 --- /dev/null +++ b/fs/nilfs2/Kconfig | |||
| @@ -0,0 +1,25 @@ | |||
| 1 | config NILFS2_FS | ||
| 2 | tristate "NILFS2 file system support (EXPERIMENTAL)" | ||
| 3 | depends on BLOCK && EXPERIMENTAL | ||
| 4 | select CRC32 | ||
| 5 | help | ||
| 6 | NILFS2 is a log-structured file system (LFS) supporting continuous | ||
| 7 | snapshotting. In addition to versioning capability of the entire | ||
| 8 | file system, users can even restore files mistakenly overwritten or | ||
| 9 | destroyed just a few seconds ago. Since this file system can keep | ||
| 10 | consistency like conventional LFS, it achieves quick recovery after | ||
| 11 | system crashes. | ||
| 12 | |||
| 13 | NILFS2 creates a number of checkpoints every few seconds or per | ||
| 14 | synchronous write basis (unless there is no change). Users can | ||
| 15 | select significant versions among continuously created checkpoints, | ||
| 16 | and can change them into snapshots which will be preserved for long | ||
| 17 | periods until they are changed back to checkpoints. Each | ||
| 18 | snapshot is mountable as a read-only file system concurrently with | ||
| 19 | its writable mount, and this feature is convenient for online backup. | ||
| 20 | |||
| 21 | Some features including atime, extended attributes, and POSIX ACLs, | ||
| 22 | are not supported yet. | ||
| 23 | |||
| 24 | To compile this file system support as a module, choose M here: the | ||
| 25 | module will be called nilfs2. If unsure, say N. | ||
diff --git a/fs/nilfs2/bmap.c b/fs/nilfs2/bmap.c index 36df60b6d8a4..99d58a028b94 100644 --- a/fs/nilfs2/bmap.c +++ b/fs/nilfs2/bmap.c | |||
| @@ -568,6 +568,7 @@ void nilfs_bmap_abort_update_v(struct nilfs_bmap *bmap, | |||
| 568 | } | 568 | } |
| 569 | 569 | ||
| 570 | static struct lock_class_key nilfs_bmap_dat_lock_key; | 570 | static struct lock_class_key nilfs_bmap_dat_lock_key; |
| 571 | static struct lock_class_key nilfs_bmap_mdt_lock_key; | ||
| 571 | 572 | ||
| 572 | /** | 573 | /** |
| 573 | * nilfs_bmap_read - read a bmap from an inode | 574 | * nilfs_bmap_read - read a bmap from an inode |
| @@ -603,7 +604,11 @@ int nilfs_bmap_read(struct nilfs_bmap *bmap, struct nilfs_inode *raw_inode) | |||
| 603 | bmap->b_ptr_type = NILFS_BMAP_PTR_VS; | 604 | bmap->b_ptr_type = NILFS_BMAP_PTR_VS; |
| 604 | bmap->b_last_allocated_key = 0; | 605 | bmap->b_last_allocated_key = 0; |
| 605 | bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR; | 606 | bmap->b_last_allocated_ptr = NILFS_BMAP_INVALID_PTR; |
| 607 | lockdep_set_class(&bmap->b_sem, &nilfs_bmap_mdt_lock_key); | ||
| 606 | break; | 608 | break; |
| 609 | case NILFS_IFILE_INO: | ||
| 610 | lockdep_set_class(&bmap->b_sem, &nilfs_bmap_mdt_lock_key); | ||
| 611 | /* Fall through */ | ||
| 607 | default: | 612 | default: |
| 608 | bmap->b_ptr_type = NILFS_BMAP_PTR_VM; | 613 | bmap->b_ptr_type = NILFS_BMAP_PTR_VM; |
| 609 | bmap->b_last_allocated_key = 0; | 614 | bmap->b_last_allocated_key = 0; |
diff --git a/fs/nilfs2/cpfile.c b/fs/nilfs2/cpfile.c index 7d49813f66d6..aec942cf79e3 100644 --- a/fs/nilfs2/cpfile.c +++ b/fs/nilfs2/cpfile.c | |||
| @@ -307,7 +307,7 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile, | |||
| 307 | ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh); | 307 | ret = nilfs_cpfile_get_checkpoint_block(cpfile, cno, 0, &cp_bh); |
| 308 | if (ret < 0) { | 308 | if (ret < 0) { |
| 309 | if (ret != -ENOENT) | 309 | if (ret != -ENOENT) |
| 310 | goto out_header; | 310 | break; |
| 311 | /* skip hole */ | 311 | /* skip hole */ |
| 312 | ret = 0; | 312 | ret = 0; |
| 313 | continue; | 313 | continue; |
| @@ -340,7 +340,7 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile, | |||
| 340 | continue; | 340 | continue; |
| 341 | printk(KERN_ERR "%s: cannot delete block\n", | 341 | printk(KERN_ERR "%s: cannot delete block\n", |
| 342 | __func__); | 342 | __func__); |
| 343 | goto out_header; | 343 | break; |
| 344 | } | 344 | } |
| 345 | } | 345 | } |
| 346 | 346 | ||
| @@ -358,7 +358,6 @@ int nilfs_cpfile_delete_checkpoints(struct inode *cpfile, | |||
| 358 | kunmap_atomic(kaddr, KM_USER0); | 358 | kunmap_atomic(kaddr, KM_USER0); |
| 359 | } | 359 | } |
| 360 | 360 | ||
| 361 | out_header: | ||
| 362 | brelse(header_bh); | 361 | brelse(header_bh); |
| 363 | 362 | ||
| 364 | out_sem: | 363 | out_sem: |
diff --git a/fs/nilfs2/dat.c b/fs/nilfs2/dat.c index 0b2710e2d565..8927ca27e6f7 100644 --- a/fs/nilfs2/dat.c +++ b/fs/nilfs2/dat.c | |||
| @@ -134,15 +134,6 @@ void nilfs_dat_commit_start(struct inode *dat, struct nilfs_palloc_req *req, | |||
| 134 | entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr, | 134 | entry = nilfs_palloc_block_get_entry(dat, req->pr_entry_nr, |
| 135 | req->pr_entry_bh, kaddr); | 135 | req->pr_entry_bh, kaddr); |
| 136 | entry->de_start = cpu_to_le64(nilfs_mdt_cno(dat)); | 136 | entry->de_start = cpu_to_le64(nilfs_mdt_cno(dat)); |
| 137 | if (entry->de_blocknr != cpu_to_le64(0) || | ||
| 138 | entry->de_end != cpu_to_le64(NILFS_CNO_MAX)) { | ||
| 139 | printk(KERN_CRIT | ||
| 140 | "%s: vbn = %llu, start = %llu, end = %llu, pbn = %llu\n", | ||
| 141 | __func__, (unsigned long long)req->pr_entry_nr, | ||
| 142 | (unsigned long long)le64_to_cpu(entry->de_start), | ||
| 143 | (unsigned long long)le64_to_cpu(entry->de_end), | ||
| 144 | (unsigned long long)le64_to_cpu(entry->de_blocknr)); | ||
| 145 | } | ||
| 146 | entry->de_blocknr = cpu_to_le64(blocknr); | 137 | entry->de_blocknr = cpu_to_le64(blocknr); |
| 147 | kunmap_atomic(kaddr, KM_USER0); | 138 | kunmap_atomic(kaddr, KM_USER0); |
| 148 | 139 | ||
diff --git a/fs/nilfs2/dir.c b/fs/nilfs2/dir.c index 54100acc1102..1a4fa04cf071 100644 --- a/fs/nilfs2/dir.c +++ b/fs/nilfs2/dir.c | |||
| @@ -43,7 +43,6 @@ | |||
| 43 | */ | 43 | */ |
| 44 | 44 | ||
| 45 | #include <linux/pagemap.h> | 45 | #include <linux/pagemap.h> |
| 46 | #include <linux/smp_lock.h> | ||
| 47 | #include "nilfs.h" | 46 | #include "nilfs.h" |
| 48 | #include "page.h" | 47 | #include "page.h" |
| 49 | 48 | ||
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index aa977549919e..8b5e4778cf28 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c | |||
| @@ -1829,26 +1829,13 @@ static int nilfs_segctor_write(struct nilfs_sc_info *sci, | |||
| 1829 | err = nilfs_segbuf_write(segbuf, &wi); | 1829 | err = nilfs_segbuf_write(segbuf, &wi); |
| 1830 | 1830 | ||
| 1831 | res = nilfs_segbuf_wait(segbuf, &wi); | 1831 | res = nilfs_segbuf_wait(segbuf, &wi); |
| 1832 | err = unlikely(err) ? : res; | 1832 | err = err ? : res; |
| 1833 | if (unlikely(err)) | 1833 | if (err) |
| 1834 | return err; | 1834 | return err; |
| 1835 | } | 1835 | } |
| 1836 | return 0; | 1836 | return 0; |
| 1837 | } | 1837 | } |
| 1838 | 1838 | ||
| 1839 | static int nilfs_page_has_uncleared_buffer(struct page *page) | ||
| 1840 | { | ||
| 1841 | struct buffer_head *head, *bh; | ||
| 1842 | |||
| 1843 | head = bh = page_buffers(page); | ||
| 1844 | do { | ||
| 1845 | if (buffer_dirty(bh) && !list_empty(&bh->b_assoc_buffers)) | ||
| 1846 | return 1; | ||
| 1847 | bh = bh->b_this_page; | ||
| 1848 | } while (bh != head); | ||
| 1849 | return 0; | ||
| 1850 | } | ||
| 1851 | |||
| 1852 | static void __nilfs_end_page_io(struct page *page, int err) | 1839 | static void __nilfs_end_page_io(struct page *page, int err) |
| 1853 | { | 1840 | { |
| 1854 | if (!err) { | 1841 | if (!err) { |
| @@ -1872,12 +1859,11 @@ static void nilfs_end_page_io(struct page *page, int err) | |||
| 1872 | if (!page) | 1859 | if (!page) |
| 1873 | return; | 1860 | return; |
| 1874 | 1861 | ||
| 1875 | if (buffer_nilfs_node(page_buffers(page)) && | 1862 | if (buffer_nilfs_node(page_buffers(page)) && !PageWriteback(page)) |
| 1876 | nilfs_page_has_uncleared_buffer(page)) | 1863 | /* |
| 1877 | /* For b-tree node pages, this function may be called twice | 1864 | * For b-tree node pages, this function may be called twice |
| 1878 | or more because they might be split in a segment. | 1865 | * or more because they might be split in a segment. |
| 1879 | This check assures that cleanup has been done for all | 1866 | */ |
| 1880 | buffers in a split btnode page. */ | ||
| 1881 | return; | 1867 | return; |
| 1882 | 1868 | ||
| 1883 | __nilfs_end_page_io(page, err); | 1869 | __nilfs_end_page_io(page, err); |
| @@ -1940,7 +1926,7 @@ static void nilfs_segctor_abort_write(struct nilfs_sc_info *sci, | |||
| 1940 | } | 1926 | } |
| 1941 | if (bh->b_page != fs_page) { | 1927 | if (bh->b_page != fs_page) { |
| 1942 | nilfs_end_page_io(fs_page, err); | 1928 | nilfs_end_page_io(fs_page, err); |
| 1943 | if (unlikely(fs_page == failed_page)) | 1929 | if (fs_page && fs_page == failed_page) |
| 1944 | goto done; | 1930 | goto done; |
| 1945 | fs_page = bh->b_page; | 1931 | fs_page = bh->b_page; |
| 1946 | } | 1932 | } |
diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c index 9fcd36dcc9a0..467b413bec21 100644 --- a/fs/ocfs2/ioctl.c +++ b/fs/ocfs2/ioctl.c | |||
| @@ -7,7 +7,6 @@ | |||
| 7 | 7 | ||
| 8 | #include <linux/fs.h> | 8 | #include <linux/fs.h> |
| 9 | #include <linux/mount.h> | 9 | #include <linux/mount.h> |
| 10 | #include <linux/smp_lock.h> | ||
| 11 | 10 | ||
| 12 | #define MLOG_MASK_PREFIX ML_INODE | 11 | #define MLOG_MASK_PREFIX ML_INODE |
| 13 | #include <cluster/masklog.h> | 12 | #include <cluster/masklog.h> |
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 1a9c7878f864..ea4e6cb29e13 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
| @@ -436,7 +436,7 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno, | |||
| 436 | rcu_assign_pointer(ptbl->part[partno], p); | 436 | rcu_assign_pointer(ptbl->part[partno], p); |
| 437 | 437 | ||
| 438 | /* suppress uevent if the disk supresses it */ | 438 | /* suppress uevent if the disk supresses it */ |
| 439 | if (!dev_get_uevent_suppress(pdev)) | 439 | if (!dev_get_uevent_suppress(ddev)) |
| 440 | kobject_uevent(&pdev->kobj, KOBJ_ADD); | 440 | kobject_uevent(&pdev->kobj, KOBJ_ADD); |
| 441 | 441 | ||
| 442 | return p; | 442 | return p; |
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index f3d47d856848..6925b835a43b 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
| @@ -46,7 +46,6 @@ | |||
| 46 | #include <linux/reiserfs_acl.h> | 46 | #include <linux/reiserfs_acl.h> |
| 47 | #include <asm/uaccess.h> | 47 | #include <asm/uaccess.h> |
| 48 | #include <net/checksum.h> | 48 | #include <net/checksum.h> |
| 49 | #include <linux/smp_lock.h> | ||
| 50 | #include <linux/stat.h> | 49 | #include <linux/stat.h> |
| 51 | #include <linux/quotaops.h> | 50 | #include <linux/quotaops.h> |
| 52 | 51 | ||
diff --git a/fs/squashfs/super.c b/fs/squashfs/super.c index 3b52770f46ff..cb5fc57e370b 100644 --- a/fs/squashfs/super.c +++ b/fs/squashfs/super.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include <linux/fs.h> | 30 | #include <linux/fs.h> |
| 31 | #include <linux/vfs.h> | 31 | #include <linux/vfs.h> |
| 32 | #include <linux/slab.h> | 32 | #include <linux/slab.h> |
| 33 | #include <linux/smp_lock.h> | ||
| 33 | #include <linux/mutex.h> | 34 | #include <linux/mutex.h> |
| 34 | #include <linux/pagemap.h> | 35 | #include <linux/pagemap.h> |
| 35 | #include <linux/init.h> | 36 | #include <linux/init.h> |
diff --git a/fs/ubifs/io.c b/fs/ubifs/io.c index bc5857199ec2..762a7d6cec73 100644 --- a/fs/ubifs/io.c +++ b/fs/ubifs/io.c | |||
| @@ -297,6 +297,7 @@ static enum hrtimer_restart wbuf_timer_callback_nolock(struct hrtimer *timer) | |||
| 297 | { | 297 | { |
| 298 | struct ubifs_wbuf *wbuf = container_of(timer, struct ubifs_wbuf, timer); | 298 | struct ubifs_wbuf *wbuf = container_of(timer, struct ubifs_wbuf, timer); |
| 299 | 299 | ||
| 300 | dbg_io("jhead %d", wbuf->jhead); | ||
| 300 | wbuf->need_sync = 1; | 301 | wbuf->need_sync = 1; |
| 301 | wbuf->c->need_wbuf_sync = 1; | 302 | wbuf->c->need_wbuf_sync = 1; |
| 302 | ubifs_wake_up_bgt(wbuf->c); | 303 | ubifs_wake_up_bgt(wbuf->c); |
| @@ -311,8 +312,12 @@ static void new_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) | |||
| 311 | { | 312 | { |
| 312 | ubifs_assert(!hrtimer_active(&wbuf->timer)); | 313 | ubifs_assert(!hrtimer_active(&wbuf->timer)); |
| 313 | 314 | ||
| 314 | if (!ktime_to_ns(wbuf->softlimit)) | 315 | if (wbuf->no_timer) |
| 315 | return; | 316 | return; |
| 317 | dbg_io("set timer for jhead %d, %llu-%llu millisecs", wbuf->jhead, | ||
| 318 | div_u64(ktime_to_ns(wbuf->softlimit), USEC_PER_SEC), | ||
| 319 | div_u64(ktime_to_ns(wbuf->softlimit) + wbuf->delta, | ||
| 320 | USEC_PER_SEC)); | ||
| 316 | hrtimer_start_range_ns(&wbuf->timer, wbuf->softlimit, wbuf->delta, | 321 | hrtimer_start_range_ns(&wbuf->timer, wbuf->softlimit, wbuf->delta, |
| 317 | HRTIMER_MODE_REL); | 322 | HRTIMER_MODE_REL); |
| 318 | } | 323 | } |
| @@ -323,11 +328,8 @@ static void new_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) | |||
| 323 | */ | 328 | */ |
| 324 | static void cancel_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) | 329 | static void cancel_wbuf_timer_nolock(struct ubifs_wbuf *wbuf) |
| 325 | { | 330 | { |
| 326 | /* | 331 | if (wbuf->no_timer) |
| 327 | * If the syncer is waiting for the lock (from the background thread's | 332 | return; |
| 328 | * context) and another task is changing write-buffer then the syncing | ||
| 329 | * should be canceled. | ||
| 330 | */ | ||
| 331 | wbuf->need_sync = 0; | 333 | wbuf->need_sync = 0; |
| 332 | hrtimer_cancel(&wbuf->timer); | 334 | hrtimer_cancel(&wbuf->timer); |
| 333 | } | 335 | } |
| @@ -349,8 +351,8 @@ int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf) | |||
| 349 | /* Write-buffer is empty or not seeked */ | 351 | /* Write-buffer is empty or not seeked */ |
| 350 | return 0; | 352 | return 0; |
| 351 | 353 | ||
| 352 | dbg_io("LEB %d:%d, %d bytes", | 354 | dbg_io("LEB %d:%d, %d bytes, jhead %d", |
| 353 | wbuf->lnum, wbuf->offs, wbuf->used); | 355 | wbuf->lnum, wbuf->offs, wbuf->used, wbuf->jhead); |
| 354 | ubifs_assert(!(c->vfs_sb->s_flags & MS_RDONLY)); | 356 | ubifs_assert(!(c->vfs_sb->s_flags & MS_RDONLY)); |
| 355 | ubifs_assert(!(wbuf->avail & 7)); | 357 | ubifs_assert(!(wbuf->avail & 7)); |
| 356 | ubifs_assert(wbuf->offs + c->min_io_size <= c->leb_size); | 358 | ubifs_assert(wbuf->offs + c->min_io_size <= c->leb_size); |
| @@ -390,7 +392,7 @@ int ubifs_wbuf_sync_nolock(struct ubifs_wbuf *wbuf) | |||
| 390 | * @offs: logical eraseblock offset to seek to | 392 | * @offs: logical eraseblock offset to seek to |
| 391 | * @dtype: data type | 393 | * @dtype: data type |
| 392 | * | 394 | * |
| 393 | * This function targets the write buffer to logical eraseblock @lnum:@offs. | 395 | * This function targets the write-buffer to logical eraseblock @lnum:@offs. |
| 394 | * The write-buffer is synchronized if it is not empty. Returns zero in case of | 396 | * The write-buffer is synchronized if it is not empty. Returns zero in case of |
| 395 | * success and a negative error code in case of failure. | 397 | * success and a negative error code in case of failure. |
| 396 | */ | 398 | */ |
| @@ -399,7 +401,7 @@ int ubifs_wbuf_seek_nolock(struct ubifs_wbuf *wbuf, int lnum, int offs, | |||
| 399 | { | 401 | { |
| 400 | const struct ubifs_info *c = wbuf->c; | 402 | const struct ubifs_info *c = wbuf->c; |
| 401 | 403 | ||
| 402 | dbg_io("LEB %d:%d", lnum, offs); | 404 | dbg_io("LEB %d:%d, jhead %d", lnum, offs, wbuf->jhead); |
| 403 | ubifs_assert(lnum >= 0 && lnum < c->leb_cnt); | 405 | ubifs_assert(lnum >= 0 && lnum < c->leb_cnt); |
| 404 | ubifs_assert(offs >= 0 && offs <= c->leb_size); | 406 | ubifs_assert(offs >= 0 && offs <= c->leb_size); |
| 405 | ubifs_assert(offs % c->min_io_size == 0 && !(offs & 7)); | 407 | ubifs_assert(offs % c->min_io_size == 0 && !(offs & 7)); |
| @@ -506,9 +508,9 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) | |||
| 506 | struct ubifs_info *c = wbuf->c; | 508 | struct ubifs_info *c = wbuf->c; |
| 507 | int err, written, n, aligned_len = ALIGN(len, 8), offs; | 509 | int err, written, n, aligned_len = ALIGN(len, 8), offs; |
| 508 | 510 | ||
| 509 | dbg_io("%d bytes (%s) to wbuf at LEB %d:%d", len, | 511 | dbg_io("%d bytes (%s) to jhead %d wbuf at LEB %d:%d", len, |
| 510 | dbg_ntype(((struct ubifs_ch *)buf)->node_type), wbuf->lnum, | 512 | dbg_ntype(((struct ubifs_ch *)buf)->node_type), wbuf->jhead, |
| 511 | wbuf->offs + wbuf->used); | 513 | wbuf->lnum, wbuf->offs + wbuf->used); |
| 512 | ubifs_assert(len > 0 && wbuf->lnum >= 0 && wbuf->lnum < c->leb_cnt); | 514 | ubifs_assert(len > 0 && wbuf->lnum >= 0 && wbuf->lnum < c->leb_cnt); |
| 513 | ubifs_assert(wbuf->offs >= 0 && wbuf->offs % c->min_io_size == 0); | 515 | ubifs_assert(wbuf->offs >= 0 && wbuf->offs % c->min_io_size == 0); |
| 514 | ubifs_assert(!(wbuf->offs & 7) && wbuf->offs <= c->leb_size); | 516 | ubifs_assert(!(wbuf->offs & 7) && wbuf->offs <= c->leb_size); |
| @@ -533,8 +535,8 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) | |||
| 533 | memcpy(wbuf->buf + wbuf->used, buf, len); | 535 | memcpy(wbuf->buf + wbuf->used, buf, len); |
| 534 | 536 | ||
| 535 | if (aligned_len == wbuf->avail) { | 537 | if (aligned_len == wbuf->avail) { |
| 536 | dbg_io("flush wbuf to LEB %d:%d", wbuf->lnum, | 538 | dbg_io("flush jhead %d wbuf to LEB %d:%d", |
| 537 | wbuf->offs); | 539 | wbuf->jhead, wbuf->lnum, wbuf->offs); |
| 538 | err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, | 540 | err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, |
| 539 | wbuf->offs, c->min_io_size, | 541 | wbuf->offs, c->min_io_size, |
| 540 | wbuf->dtype); | 542 | wbuf->dtype); |
| @@ -562,7 +564,8 @@ int ubifs_wbuf_write_nolock(struct ubifs_wbuf *wbuf, void *buf, int len) | |||
| 562 | * minimal I/O unit. We have to fill and flush write-buffer and switch | 564 | * minimal I/O unit. We have to fill and flush write-buffer and switch |
| 563 | * to the next min. I/O unit. | 565 | * to the next min. I/O unit. |
| 564 | */ | 566 | */ |
| 565 | dbg_io("flush wbuf to LEB %d:%d", wbuf->lnum, wbuf->offs); | 567 | dbg_io("flush jhead %d wbuf to LEB %d:%d", |
| 568 | wbuf->jhead, wbuf->lnum, wbuf->offs); | ||
| 566 | memcpy(wbuf->buf + wbuf->used, buf, wbuf->avail); | 569 | memcpy(wbuf->buf + wbuf->used, buf, wbuf->avail); |
| 567 | err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, wbuf->offs, | 570 | err = ubi_leb_write(c->ubi, wbuf->lnum, wbuf->buf, wbuf->offs, |
| 568 | c->min_io_size, wbuf->dtype); | 571 | c->min_io_size, wbuf->dtype); |
| @@ -695,7 +698,8 @@ int ubifs_read_node_wbuf(struct ubifs_wbuf *wbuf, void *buf, int type, int len, | |||
| 695 | int err, rlen, overlap; | 698 | int err, rlen, overlap; |
| 696 | struct ubifs_ch *ch = buf; | 699 | struct ubifs_ch *ch = buf; |
| 697 | 700 | ||
| 698 | dbg_io("LEB %d:%d, %s, length %d", lnum, offs, dbg_ntype(type), len); | 701 | dbg_io("LEB %d:%d, %s, length %d, jhead %d", lnum, offs, |
| 702 | dbg_ntype(type), len, wbuf->jhead); | ||
| 699 | ubifs_assert(wbuf && lnum >= 0 && lnum < c->leb_cnt && offs >= 0); | 703 | ubifs_assert(wbuf && lnum >= 0 && lnum < c->leb_cnt && offs >= 0); |
| 700 | ubifs_assert(!(offs & 7) && offs < c->leb_size); | 704 | ubifs_assert(!(offs & 7) && offs < c->leb_size); |
| 701 | ubifs_assert(type >= 0 && type < UBIFS_NODE_TYPES_CNT); | 705 | ubifs_assert(type >= 0 && type < UBIFS_NODE_TYPES_CNT); |
| @@ -819,13 +823,12 @@ out: | |||
| 819 | * @c: UBIFS file-system description object | 823 | * @c: UBIFS file-system description object |
| 820 | * @wbuf: write-buffer to initialize | 824 | * @wbuf: write-buffer to initialize |
| 821 | * | 825 | * |
| 822 | * This function initializes write buffer. Returns zero in case of success | 826 | * This function initializes write-buffer. Returns zero in case of success |
| 823 | * %-ENOMEM in case of failure. | 827 | * %-ENOMEM in case of failure. |
| 824 | */ | 828 | */ |
| 825 | int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) | 829 | int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) |
| 826 | { | 830 | { |
| 827 | size_t size; | 831 | size_t size; |
| 828 | ktime_t hardlimit; | ||
| 829 | 832 | ||
| 830 | wbuf->buf = kmalloc(c->min_io_size, GFP_KERNEL); | 833 | wbuf->buf = kmalloc(c->min_io_size, GFP_KERNEL); |
| 831 | if (!wbuf->buf) | 834 | if (!wbuf->buf) |
| @@ -851,22 +854,16 @@ int ubifs_wbuf_init(struct ubifs_info *c, struct ubifs_wbuf *wbuf) | |||
| 851 | 854 | ||
| 852 | hrtimer_init(&wbuf->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | 855 | hrtimer_init(&wbuf->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); |
| 853 | wbuf->timer.function = wbuf_timer_callback_nolock; | 856 | wbuf->timer.function = wbuf_timer_callback_nolock; |
| 854 | /* | 857 | wbuf->softlimit = ktime_set(WBUF_TIMEOUT_SOFTLIMIT, 0); |
| 855 | * Make write-buffer soft limit to be 20% of the hard limit. The | 858 | wbuf->delta = WBUF_TIMEOUT_HARDLIMIT - WBUF_TIMEOUT_SOFTLIMIT; |
| 856 | * write-buffer timer is allowed to expire any time between the soft | 859 | wbuf->delta *= 1000000000ULL; |
| 857 | * and hard limits. | 860 | ubifs_assert(wbuf->delta <= ULONG_MAX); |
| 858 | */ | ||
| 859 | hardlimit = ktime_set(DEFAULT_WBUF_TIMEOUT_SECS, 0); | ||
| 860 | wbuf->delta = (DEFAULT_WBUF_TIMEOUT_SECS * NSEC_PER_SEC) * 2 / 10; | ||
| 861 | wbuf->softlimit = ktime_sub_ns(hardlimit, wbuf->delta); | ||
| 862 | hrtimer_set_expires_range_ns(&wbuf->timer, wbuf->softlimit, | ||
| 863 | wbuf->delta); | ||
| 864 | return 0; | 861 | return 0; |
| 865 | } | 862 | } |
| 866 | 863 | ||
| 867 | /** | 864 | /** |
| 868 | * ubifs_wbuf_add_ino_nolock - add an inode number into the wbuf inode array. | 865 | * ubifs_wbuf_add_ino_nolock - add an inode number into the wbuf inode array. |
| 869 | * @wbuf: the write-buffer whereto add | 866 | * @wbuf: the write-buffer where to add |
| 870 | * @inum: the inode number | 867 | * @inum: the inode number |
| 871 | * | 868 | * |
| 872 | * This function adds an inode number to the inode array of the write-buffer. | 869 | * This function adds an inode number to the inode array of the write-buffer. |
diff --git a/fs/ubifs/ioctl.c b/fs/ubifs/ioctl.c index 6db7a6be6c97..8aacd64957a2 100644 --- a/fs/ubifs/ioctl.c +++ b/fs/ubifs/ioctl.c | |||
| @@ -25,7 +25,6 @@ | |||
| 25 | /* This file implements EXT2-compatible extended attribute ioctl() calls */ | 25 | /* This file implements EXT2-compatible extended attribute ioctl() calls */ |
| 26 | 26 | ||
| 27 | #include <linux/compat.h> | 27 | #include <linux/compat.h> |
| 28 | #include <linux/smp_lock.h> | ||
| 29 | #include <linux/mount.h> | 28 | #include <linux/mount.h> |
| 30 | #include "ubifs.h" | 29 | #include "ubifs.h" |
| 31 | 30 | ||
diff --git a/fs/ubifs/recovery.c b/fs/ubifs/recovery.c index 805605250f12..e5f6cf8a1155 100644 --- a/fs/ubifs/recovery.c +++ b/fs/ubifs/recovery.c | |||
| @@ -53,6 +53,25 @@ static int is_empty(void *buf, int len) | |||
| 53 | } | 53 | } |
| 54 | 54 | ||
| 55 | /** | 55 | /** |
| 56 | * first_non_ff - find offset of the first non-0xff byte. | ||
| 57 | * @buf: buffer to search in | ||
| 58 | * @len: length of buffer | ||
| 59 | * | ||
| 60 | * This function returns offset of the first non-0xff byte in @buf or %-1 if | ||
| 61 | * the buffer contains only 0xff bytes. | ||
| 62 | */ | ||
| 63 | static int first_non_ff(void *buf, int len) | ||
| 64 | { | ||
| 65 | uint8_t *p = buf; | ||
| 66 | int i; | ||
| 67 | |||
| 68 | for (i = 0; i < len; i++) | ||
| 69 | if (*p++ != 0xff) | ||
| 70 | return i; | ||
| 71 | return -1; | ||
| 72 | } | ||
| 73 | |||
| 74 | /** | ||
| 56 | * get_master_node - get the last valid master node allowing for corruption. | 75 | * get_master_node - get the last valid master node allowing for corruption. |
| 57 | * @c: UBIFS file-system description object | 76 | * @c: UBIFS file-system description object |
| 58 | * @lnum: LEB number | 77 | * @lnum: LEB number |
| @@ -357,11 +376,7 @@ static int is_last_write(const struct ubifs_info *c, void *buf, int offs) | |||
| 357 | empty_offs = ALIGN(offs + 1, c->min_io_size); | 376 | empty_offs = ALIGN(offs + 1, c->min_io_size); |
| 358 | check_len = c->leb_size - empty_offs; | 377 | check_len = c->leb_size - empty_offs; |
| 359 | p = buf + empty_offs - offs; | 378 | p = buf + empty_offs - offs; |
| 360 | 379 | return is_empty(p, check_len); | |
| 361 | for (; check_len > 0; check_len--) | ||
| 362 | if (*p++ != 0xff) | ||
| 363 | return 0; | ||
| 364 | return 1; | ||
| 365 | } | 380 | } |
| 366 | 381 | ||
| 367 | /** | 382 | /** |
| @@ -543,8 +558,8 @@ static int drop_incomplete_group(struct ubifs_scan_leb *sleb, int *offs) | |||
| 543 | * | 558 | * |
| 544 | * This function does a scan of a LEB, but caters for errors that might have | 559 | * This function does a scan of a LEB, but caters for errors that might have |
| 545 | * been caused by the unclean unmount from which we are attempting to recover. | 560 | * been caused by the unclean unmount from which we are attempting to recover. |
| 546 | * | 561 | * Returns %0 in case of success, %-EUCLEAN if an unrecoverable corruption is |
| 547 | * This function returns %0 on success and a negative error code on failure. | 562 | * found, and a negative error code in case of failure. |
| 548 | */ | 563 | */ |
| 549 | struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, | 564 | struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, |
| 550 | int offs, void *sbuf, int grouped) | 565 | int offs, void *sbuf, int grouped) |
| @@ -643,7 +658,8 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, | |||
| 643 | goto corrupted; | 658 | goto corrupted; |
| 644 | default: | 659 | default: |
| 645 | dbg_err("unknown"); | 660 | dbg_err("unknown"); |
| 646 | goto corrupted; | 661 | err = -EINVAL; |
| 662 | goto error; | ||
| 647 | } | 663 | } |
| 648 | } | 664 | } |
| 649 | 665 | ||
| @@ -652,8 +668,13 @@ struct ubifs_scan_leb *ubifs_recover_leb(struct ubifs_info *c, int lnum, | |||
| 652 | clean_buf(c, &buf, lnum, &offs, &len); | 668 | clean_buf(c, &buf, lnum, &offs, &len); |
| 653 | need_clean = 1; | 669 | need_clean = 1; |
| 654 | } else { | 670 | } else { |
| 655 | ubifs_err("corrupt empty space at LEB %d:%d", | 671 | int corruption = first_non_ff(buf, len); |
| 656 | lnum, offs); | 672 | |
| 673 | ubifs_err("corrupt empty space LEB %d:%d, corruption " | ||
| 674 | "starts at %d", lnum, offs, corruption); | ||
| 675 | /* Make sure we dump interesting non-0xFF data */ | ||
| 676 | offs = corruption; | ||
| 677 | buf += corruption; | ||
| 657 | goto corrupted; | 678 | goto corrupted; |
| 658 | } | 679 | } |
| 659 | } | 680 | } |
| @@ -813,7 +834,7 @@ struct ubifs_scan_leb *ubifs_recover_log_leb(struct ubifs_info *c, int lnum, | |||
| 813 | static int recover_head(const struct ubifs_info *c, int lnum, int offs, | 834 | static int recover_head(const struct ubifs_info *c, int lnum, int offs, |
| 814 | void *sbuf) | 835 | void *sbuf) |
| 815 | { | 836 | { |
| 816 | int len, err, need_clean = 0; | 837 | int len, err; |
| 817 | 838 | ||
| 818 | if (c->min_io_size > 1) | 839 | if (c->min_io_size > 1) |
| 819 | len = c->min_io_size; | 840 | len = c->min_io_size; |
| @@ -827,19 +848,7 @@ static int recover_head(const struct ubifs_info *c, int lnum, int offs, | |||
| 827 | 848 | ||
| 828 | /* Read at the head location and check it is empty flash */ | 849 | /* Read at the head location and check it is empty flash */ |
| 829 | err = ubi_read(c->ubi, lnum, sbuf, offs, len); | 850 | err = ubi_read(c->ubi, lnum, sbuf, offs, len); |
| 830 | if (err) | 851 | if (err || !is_empty(sbuf, len)) { |
| 831 | need_clean = 1; | ||
| 832 | else { | ||
| 833 | uint8_t *p = sbuf; | ||
| 834 | |||
| 835 | while (len--) | ||
| 836 | if (*p++ != 0xff) { | ||
| 837 | need_clean = 1; | ||
| 838 | break; | ||
| 839 | } | ||
| 840 | } | ||
| 841 | |||
| 842 | if (need_clean) { | ||
| 843 | dbg_rcvry("cleaning head at %d:%d", lnum, offs); | 852 | dbg_rcvry("cleaning head at %d:%d", lnum, offs); |
| 844 | if (offs == 0) | 853 | if (offs == 0) |
| 845 | return ubifs_leb_unmap(c, lnum); | 854 | return ubifs_leb_unmap(c, lnum); |
diff --git a/fs/ubifs/replay.c b/fs/ubifs/replay.c index 11cc80125a49..2970500f32df 100644 --- a/fs/ubifs/replay.c +++ b/fs/ubifs/replay.c | |||
| @@ -837,9 +837,10 @@ static int replay_log_leb(struct ubifs_info *c, int lnum, int offs, void *sbuf) | |||
| 837 | 837 | ||
| 838 | dbg_mnt("replay log LEB %d:%d", lnum, offs); | 838 | dbg_mnt("replay log LEB %d:%d", lnum, offs); |
| 839 | sleb = ubifs_scan(c, lnum, offs, sbuf); | 839 | sleb = ubifs_scan(c, lnum, offs, sbuf); |
| 840 | if (IS_ERR(sleb)) { | 840 | if (IS_ERR(sleb) ) { |
| 841 | if (c->need_recovery) | 841 | if (PTR_ERR(sleb) != -EUCLEAN || !c->need_recovery) |
| 842 | sleb = ubifs_recover_log_leb(c, lnum, offs, sbuf); | 842 | return PTR_ERR(sleb); |
| 843 | sleb = ubifs_recover_log_leb(c, lnum, offs, sbuf); | ||
| 843 | if (IS_ERR(sleb)) | 844 | if (IS_ERR(sleb)) |
| 844 | return PTR_ERR(sleb); | 845 | return PTR_ERR(sleb); |
| 845 | } | 846 | } |
| @@ -957,7 +958,7 @@ out: | |||
| 957 | return err; | 958 | return err; |
| 958 | 959 | ||
| 959 | out_dump: | 960 | out_dump: |
| 960 | ubifs_err("log error detected while replying the log at LEB %d:%d", | 961 | ubifs_err("log error detected while replaying the log at LEB %d:%d", |
| 961 | lnum, offs + snod->offs); | 962 | lnum, offs + snod->offs); |
| 962 | dbg_dump_node(c, snod->node); | 963 | dbg_dump_node(c, snod->node); |
| 963 | ubifs_scan_destroy(sleb); | 964 | ubifs_scan_destroy(sleb); |
diff --git a/fs/ubifs/scan.c b/fs/ubifs/scan.c index 0ed82479b44b..892ebfee4fe5 100644 --- a/fs/ubifs/scan.c +++ b/fs/ubifs/scan.c | |||
| @@ -238,12 +238,12 @@ void ubifs_scanned_corruption(const struct ubifs_info *c, int lnum, int offs, | |||
| 238 | { | 238 | { |
| 239 | int len; | 239 | int len; |
| 240 | 240 | ||
| 241 | ubifs_err("corrupted data at LEB %d:%d", lnum, offs); | 241 | ubifs_err("corruption at LEB %d:%d", lnum, offs); |
| 242 | if (dbg_failure_mode) | 242 | if (dbg_failure_mode) |
| 243 | return; | 243 | return; |
| 244 | len = c->leb_size - offs; | 244 | len = c->leb_size - offs; |
| 245 | if (len > 4096) | 245 | if (len > 8192) |
| 246 | len = 4096; | 246 | len = 8192; |
| 247 | dbg_err("first %d bytes from LEB %d:%d", len, lnum, offs); | 247 | dbg_err("first %d bytes from LEB %d:%d", len, lnum, offs); |
| 248 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 4, buf, len, 1); | 248 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 32, 4, buf, len, 1); |
| 249 | } | 249 | } |
| @@ -256,7 +256,9 @@ void ubifs_scanned_corruption(const struct ubifs_info *c, int lnum, int offs, | |||
| 256 | * @sbuf: scan buffer (must be c->leb_size) | 256 | * @sbuf: scan buffer (must be c->leb_size) |
| 257 | * | 257 | * |
| 258 | * This function scans LEB number @lnum and returns complete information about | 258 | * This function scans LEB number @lnum and returns complete information about |
| 259 | * its contents. Returns an error code in case of failure. | 259 | * its contents. Returns the scaned information in case of success and, |
| 260 | * %-EUCLEAN if the LEB neads recovery, and other negative error codes in case | ||
| 261 | * of failure. | ||
| 260 | */ | 262 | */ |
| 261 | struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, | 263 | struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, |
| 262 | int offs, void *sbuf) | 264 | int offs, void *sbuf) |
| @@ -279,7 +281,6 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, | |||
| 279 | cond_resched(); | 281 | cond_resched(); |
| 280 | 282 | ||
| 281 | ret = ubifs_scan_a_node(c, buf, len, lnum, offs, 0); | 283 | ret = ubifs_scan_a_node(c, buf, len, lnum, offs, 0); |
| 282 | |||
| 283 | if (ret > 0) { | 284 | if (ret > 0) { |
| 284 | /* Padding bytes or a valid padding node */ | 285 | /* Padding bytes or a valid padding node */ |
| 285 | offs += ret; | 286 | offs += ret; |
| @@ -304,7 +305,8 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, | |||
| 304 | goto corrupted; | 305 | goto corrupted; |
| 305 | default: | 306 | default: |
| 306 | dbg_err("unknown"); | 307 | dbg_err("unknown"); |
| 307 | goto corrupted; | 308 | err = -EINVAL; |
| 309 | goto error; | ||
| 308 | } | 310 | } |
| 309 | 311 | ||
| 310 | err = ubifs_add_snod(c, sleb, buf, offs); | 312 | err = ubifs_add_snod(c, sleb, buf, offs); |
| @@ -317,8 +319,10 @@ struct ubifs_scan_leb *ubifs_scan(const struct ubifs_info *c, int lnum, | |||
| 317 | len -= node_len; | 319 | len -= node_len; |
| 318 | } | 320 | } |
| 319 | 321 | ||
| 320 | if (offs % c->min_io_size) | 322 | if (offs % c->min_io_size) { |
| 321 | goto corrupted; | 323 | ubifs_err("empty space starts at non-aligned offset %d", offs); |
| 324 | goto corrupted;; | ||
| 325 | } | ||
| 322 | 326 | ||
| 323 | ubifs_end_scan(c, sleb, lnum, offs); | 327 | ubifs_end_scan(c, sleb, lnum, offs); |
| 324 | 328 | ||
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 79fad43f3c57..26d2e0d80465 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
| @@ -797,7 +797,7 @@ static int alloc_wbufs(struct ubifs_info *c) | |||
| 797 | * does not need to be synchronized by timer. | 797 | * does not need to be synchronized by timer. |
| 798 | */ | 798 | */ |
| 799 | c->jheads[GCHD].wbuf.dtype = UBI_LONGTERM; | 799 | c->jheads[GCHD].wbuf.dtype = UBI_LONGTERM; |
| 800 | c->jheads[GCHD].wbuf.softlimit = ktime_set(0, 0); | 800 | c->jheads[GCHD].wbuf.no_timer = 1; |
| 801 | 801 | ||
| 802 | return 0; | 802 | return 0; |
| 803 | } | 803 | } |
| @@ -986,7 +986,7 @@ static int ubifs_parse_options(struct ubifs_info *c, char *options, | |||
| 986 | switch (token) { | 986 | switch (token) { |
| 987 | /* | 987 | /* |
| 988 | * %Opt_fast_unmount and %Opt_norm_unmount options are ignored. | 988 | * %Opt_fast_unmount and %Opt_norm_unmount options are ignored. |
| 989 | * We accepte them in order to be backware-compatible. But this | 989 | * We accept them in order to be backward-compatible. But this |
| 990 | * should be removed at some point. | 990 | * should be removed at some point. |
| 991 | */ | 991 | */ |
| 992 | case Opt_fast_unmount: | 992 | case Opt_fast_unmount: |
| @@ -1287,6 +1287,9 @@ static int mount_ubifs(struct ubifs_info *c) | |||
| 1287 | if (err) | 1287 | if (err) |
| 1288 | goto out_journal; | 1288 | goto out_journal; |
| 1289 | 1289 | ||
| 1290 | /* Calculate 'min_idx_lebs' after journal replay */ | ||
| 1291 | c->min_idx_lebs = ubifs_calc_min_idx_lebs(c); | ||
| 1292 | |||
| 1290 | err = ubifs_mount_orphans(c, c->need_recovery, mounted_read_only); | 1293 | err = ubifs_mount_orphans(c, c->need_recovery, mounted_read_only); |
| 1291 | if (err) | 1294 | if (err) |
| 1292 | goto out_orphans; | 1295 | goto out_orphans; |
| @@ -1754,10 +1757,8 @@ static void ubifs_put_super(struct super_block *sb) | |||
| 1754 | 1757 | ||
| 1755 | /* Synchronize write-buffers */ | 1758 | /* Synchronize write-buffers */ |
| 1756 | if (c->jheads) | 1759 | if (c->jheads) |
| 1757 | for (i = 0; i < c->jhead_cnt; i++) { | 1760 | for (i = 0; i < c->jhead_cnt; i++) |
| 1758 | ubifs_wbuf_sync(&c->jheads[i].wbuf); | 1761 | ubifs_wbuf_sync(&c->jheads[i].wbuf); |
| 1759 | hrtimer_cancel(&c->jheads[i].wbuf.timer); | ||
| 1760 | } | ||
| 1761 | 1762 | ||
| 1762 | /* | 1763 | /* |
| 1763 | * On fatal errors c->ro_media is set to 1, in which case we do | 1764 | * On fatal errors c->ro_media is set to 1, in which case we do |
| @@ -1975,7 +1976,8 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent) | |||
| 1975 | err = bdi_init(&c->bdi); | 1976 | err = bdi_init(&c->bdi); |
| 1976 | if (err) | 1977 | if (err) |
| 1977 | goto out_close; | 1978 | goto out_close; |
| 1978 | err = bdi_register(&c->bdi, NULL, "ubifs"); | 1979 | err = bdi_register(&c->bdi, NULL, "ubifs_%d_%d", |
| 1980 | c->vi.ubi_num, c->vi.vol_id); | ||
| 1979 | if (err) | 1981 | if (err) |
| 1980 | goto out_bdi; | 1982 | goto out_bdi; |
| 1981 | 1983 | ||
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 1bf01d820066..a29349094422 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
| @@ -95,8 +95,9 @@ | |||
| 95 | */ | 95 | */ |
| 96 | #define BGT_NAME_PATTERN "ubifs_bgt%d_%d" | 96 | #define BGT_NAME_PATTERN "ubifs_bgt%d_%d" |
| 97 | 97 | ||
| 98 | /* Default write-buffer synchronization timeout in seconds */ | 98 | /* Write-buffer synchronization timeout interval in seconds */ |
| 99 | #define DEFAULT_WBUF_TIMEOUT_SECS 5 | 99 | #define WBUF_TIMEOUT_SOFTLIMIT 3 |
| 100 | #define WBUF_TIMEOUT_HARDLIMIT 5 | ||
| 100 | 101 | ||
| 101 | /* Maximum possible inode number (only 32-bit inodes are supported now) */ | 102 | /* Maximum possible inode number (only 32-bit inodes are supported now) */ |
| 102 | #define MAX_INUM 0xFFFFFFFF | 103 | #define MAX_INUM 0xFFFFFFFF |
| @@ -654,7 +655,8 @@ typedef int (*ubifs_lpt_scan_callback)(struct ubifs_info *c, | |||
| 654 | * @delta: hard and soft timeouts delta (the timer expire inteval is @softlimit | 655 | * @delta: hard and soft timeouts delta (the timer expire inteval is @softlimit |
| 655 | * and @softlimit + @delta) | 656 | * and @softlimit + @delta) |
| 656 | * @timer: write-buffer timer | 657 | * @timer: write-buffer timer |
| 657 | * @need_sync: it is set if its timer expired and needs sync | 658 | * @no_timer: non-zero if this write-buffer does not have a timer |
| 659 | * @need_sync: non-zero if the timer expired and the wbuf needs sync'ing | ||
| 658 | * @next_ino: points to the next position of the following inode number | 660 | * @next_ino: points to the next position of the following inode number |
| 659 | * @inodes: stores the inode numbers of the nodes which are in wbuf | 661 | * @inodes: stores the inode numbers of the nodes which are in wbuf |
| 660 | * | 662 | * |
| @@ -683,7 +685,8 @@ struct ubifs_wbuf { | |||
| 683 | ktime_t softlimit; | 685 | ktime_t softlimit; |
| 684 | unsigned long long delta; | 686 | unsigned long long delta; |
| 685 | struct hrtimer timer; | 687 | struct hrtimer timer; |
| 686 | int need_sync; | 688 | unsigned int no_timer:1; |
| 689 | unsigned int need_sync:1; | ||
| 687 | int next_ino; | 690 | int next_ino; |
| 688 | ino_t *inodes; | 691 | ino_t *inodes; |
| 689 | }; | 692 | }; |
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c index f4e255441574..0542fd507649 100644 --- a/fs/xfs/linux-2.6/xfs_file.c +++ b/fs/xfs/linux-2.6/xfs_file.c | |||
| @@ -41,7 +41,6 @@ | |||
| 41 | #include "xfs_ioctl.h" | 41 | #include "xfs_ioctl.h" |
| 42 | 42 | ||
| 43 | #include <linux/dcache.h> | 43 | #include <linux/dcache.h> |
| 44 | #include <linux/smp_lock.h> | ||
| 45 | 44 | ||
| 46 | static struct vm_operations_struct xfs_file_vm_ops; | 45 | static struct vm_operations_struct xfs_file_vm_ops; |
| 47 | 46 | ||
