diff options
Diffstat (limited to 'fs')
39 files changed, 431 insertions, 291 deletions
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h index 8ada4c5c5d..6a82d39dc4 100644 --- a/fs/9p/v9fs_vfs.h +++ b/fs/9p/v9fs_vfs.h | |||
@@ -40,7 +40,6 @@ | |||
40 | extern struct file_system_type v9fs_fs_type; | 40 | extern struct file_system_type v9fs_fs_type; |
41 | extern const struct address_space_operations v9fs_addr_operations; | 41 | extern const struct address_space_operations v9fs_addr_operations; |
42 | extern const struct file_operations v9fs_file_operations; | 42 | extern const struct file_operations v9fs_file_operations; |
43 | extern const struct file_operations v9fs_cached_file_operations; | ||
44 | extern const struct file_operations v9fs_dir_operations; | 43 | extern const struct file_operations v9fs_dir_operations; |
45 | extern struct dentry_operations v9fs_dentry_operations; | 44 | extern struct dentry_operations v9fs_dentry_operations; |
46 | extern struct dentry_operations v9fs_cached_dentry_operations; | 45 | extern struct dentry_operations v9fs_cached_dentry_operations; |
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c index 653dfa5b25..c7b6772538 100644 --- a/fs/9p/vfs_file.c +++ b/fs/9p/vfs_file.c | |||
@@ -42,6 +42,8 @@ | |||
42 | #include "v9fs_vfs.h" | 42 | #include "v9fs_vfs.h" |
43 | #include "fid.h" | 43 | #include "fid.h" |
44 | 44 | ||
45 | static const struct file_operations v9fs_cached_file_operations; | ||
46 | |||
45 | /** | 47 | /** |
46 | * v9fs_file_open - open a file (or directory) | 48 | * v9fs_file_open - open a file (or directory) |
47 | * @inode: inode to be opened | 49 | * @inode: inode to be opened |
@@ -245,7 +247,7 @@ v9fs_file_write(struct file *filp, const char __user * data, | |||
245 | return total; | 247 | return total; |
246 | } | 248 | } |
247 | 249 | ||
248 | const struct file_operations v9fs_cached_file_operations = { | 250 | static const struct file_operations v9fs_cached_file_operations = { |
249 | .llseek = generic_file_llseek, | 251 | .llseek = generic_file_llseek, |
250 | .read = do_sync_read, | 252 | .read = do_sync_read, |
251 | .aio_read = generic_file_aio_read, | 253 | .aio_read = generic_file_aio_read, |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 51db1182b2..a2fceba7ef 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -507,7 +507,7 @@ out: | |||
507 | #define INTERPRETER_ELF 2 | 507 | #define INTERPRETER_ELF 2 |
508 | 508 | ||
509 | #ifndef STACK_RND_MASK | 509 | #ifndef STACK_RND_MASK |
510 | #define STACK_RND_MASK 0x7ff /* with 4K pages 8MB of VA */ | 510 | #define STACK_RND_MASK (0x7ff >> (PAGE_SHIFT - 12)) /* 8MB of VA */ |
511 | #endif | 511 | #endif |
512 | 512 | ||
513 | static unsigned long randomize_stack_top(unsigned long stack_top) | 513 | static unsigned long randomize_stack_top(unsigned long stack_top) |
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 5810aa1339..47d6d49d1f 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
@@ -179,6 +179,8 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, | |||
179 | int executable_stack; | 179 | int executable_stack; |
180 | int retval, i; | 180 | int retval, i; |
181 | 181 | ||
182 | kdebug("____ LOAD %d ____", current->pid); | ||
183 | |||
182 | memset(&exec_params, 0, sizeof(exec_params)); | 184 | memset(&exec_params, 0, sizeof(exec_params)); |
183 | memset(&interp_params, 0, sizeof(interp_params)); | 185 | memset(&interp_params, 0, sizeof(interp_params)); |
184 | 186 | ||
@@ -941,8 +943,11 @@ static int elf_fdpic_map_file_constdisp_on_uclinux( | |||
941 | 943 | ||
942 | if (mm) { | 944 | if (mm) { |
943 | if (phdr->p_flags & PF_X) { | 945 | if (phdr->p_flags & PF_X) { |
944 | mm->start_code = seg->addr; | 946 | if (!mm->start_code) { |
945 | mm->end_code = seg->addr + phdr->p_memsz; | 947 | mm->start_code = seg->addr; |
948 | mm->end_code = seg->addr + | ||
949 | phdr->p_memsz; | ||
950 | } | ||
946 | } else if (!mm->start_data) { | 951 | } else if (!mm->start_data) { |
947 | mm->start_data = seg->addr; | 952 | mm->start_data = seg->addr; |
948 | #ifndef CONFIG_MMU | 953 | #ifndef CONFIG_MMU |
@@ -1123,8 +1128,10 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params, | |||
1123 | 1128 | ||
1124 | if (mm) { | 1129 | if (mm) { |
1125 | if (phdr->p_flags & PF_X) { | 1130 | if (phdr->p_flags & PF_X) { |
1126 | mm->start_code = maddr; | 1131 | if (!mm->start_code) { |
1127 | mm->end_code = maddr + phdr->p_memsz; | 1132 | mm->start_code = maddr; |
1133 | mm->end_code = maddr + phdr->p_memsz; | ||
1134 | } | ||
1128 | } else if (!mm->start_data) { | 1135 | } else if (!mm->start_data) { |
1129 | mm->start_data = maddr; | 1136 | mm->start_data = maddr; |
1130 | mm->end_data = maddr + phdr->p_memsz; | 1137 | mm->end_data = maddr + phdr->p_memsz; |
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 6247628bda..5d1f4873d7 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
@@ -4,6 +4,12 @@ Fix mtime bouncing around from local idea of last write times to remote time. | |||
4 | Fix hang (in i_size_read) when simultaneous size update of same remote file | 4 | Fix hang (in i_size_read) when simultaneous size update of same remote file |
5 | on smp system corrupts sequence number. Do not reread unnecessarily partial page | 5 | on smp system corrupts sequence number. Do not reread unnecessarily partial page |
6 | (which we are about to overwrite anyway) when writing out file opened rw. | 6 | (which we are about to overwrite anyway) when writing out file opened rw. |
7 | When DOS attribute of file on non-Unix server's file changes on the server side | ||
8 | from read-only back to read-write, reflect this change in default file mode | ||
9 | (we had been leaving a file's mode read-only until the inode were reloaded). | ||
10 | Allow setting of attribute back to ATTR_NORMAL (removing readonly dos attribute | ||
11 | when archive dos attribute not set and we are changing mode back to writeable | ||
12 | on server which does not support the Unix Extensions). | ||
7 | 13 | ||
8 | Version 1.47 | 14 | Version 1.47 |
9 | ------------ | 15 | ------------ |
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 0efdf35aab..4d8948e876 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h | |||
@@ -220,7 +220,7 @@ | |||
220 | */ | 220 | */ |
221 | #define CIFS_NO_HANDLE 0xFFFF | 221 | #define CIFS_NO_HANDLE 0xFFFF |
222 | 222 | ||
223 | #define NO_CHANGE_64 0xFFFFFFFFFFFFFFFFULL | 223 | #define NO_CHANGE_64 cpu_to_le64(0xFFFFFFFFFFFFFFFFULL) |
224 | #define NO_CHANGE_32 0xFFFFFFFFUL | 224 | #define NO_CHANGE_32 0xFFFFFFFFUL |
225 | 225 | ||
226 | /* IPC$ in ASCII */ | 226 | /* IPC$ in ASCII */ |
@@ -1887,7 +1887,13 @@ typedef struct { | |||
1887 | calls including posix open | 1887 | calls including posix open |
1888 | and posix unlink */ | 1888 | and posix unlink */ |
1889 | #ifdef CONFIG_CIFS_POSIX | 1889 | #ifdef CONFIG_CIFS_POSIX |
1890 | #define CIFS_UNIX_CAP_MASK 0x0000003b | 1890 | /* Can not set pathnames cap yet until we send new posix create SMB since |
1891 | otherwise server can treat such handles opened with older ntcreatex | ||
1892 | (by a new client which knows how to send posix path ops) | ||
1893 | as non-posix handles (can affect write behavior with byte range locks. | ||
1894 | We can add back in POSIX_PATH_OPS cap when Posix Create/Mkdir finished */ | ||
1895 | /* #define CIFS_UNIX_CAP_MASK 0x0000003b */ | ||
1896 | #define CIFS_UNIX_CAP_MASK 0x0000001b | ||
1891 | #else | 1897 | #else |
1892 | #define CIFS_UNIX_CAP_MASK 0x00000013 | 1898 | #define CIFS_UNIX_CAP_MASK 0x00000013 |
1893 | #endif /* CONFIG_CIFS_POSIX */ | 1899 | #endif /* CONFIG_CIFS_POSIX */ |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 86b9dbbd84..f414526e47 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -494,6 +494,12 @@ int cifs_get_inode_info(struct inode **pinode, | |||
494 | mode e.g. 555 */ | 494 | mode e.g. 555 */ |
495 | if (cifsInfo->cifsAttrs & ATTR_READONLY) | 495 | if (cifsInfo->cifsAttrs & ATTR_READONLY) |
496 | inode->i_mode &= ~(S_IWUGO); | 496 | inode->i_mode &= ~(S_IWUGO); |
497 | else if ((inode->i_mode & S_IWUGO) == 0) | ||
498 | /* the ATTR_READONLY flag may have been */ | ||
499 | /* changed on server -- set any w bits */ | ||
500 | /* allowed by mnt_file_mode */ | ||
501 | inode->i_mode |= (S_IWUGO & | ||
502 | cifs_sb->mnt_file_mode); | ||
497 | /* BB add code here - | 503 | /* BB add code here - |
498 | validate if device or weird share or device type? */ | 504 | validate if device or weird share or device type? */ |
499 | } | 505 | } |
@@ -1190,6 +1196,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
1190 | struct cifsFileInfo *open_file = NULL; | 1196 | struct cifsFileInfo *open_file = NULL; |
1191 | FILE_BASIC_INFO time_buf; | 1197 | FILE_BASIC_INFO time_buf; |
1192 | int set_time = FALSE; | 1198 | int set_time = FALSE; |
1199 | int set_dosattr = FALSE; | ||
1193 | __u64 mode = 0xFFFFFFFFFFFFFFFFULL; | 1200 | __u64 mode = 0xFFFFFFFFFFFFFFFFULL; |
1194 | __u64 uid = 0xFFFFFFFFFFFFFFFFULL; | 1201 | __u64 uid = 0xFFFFFFFFFFFFFFFFULL; |
1195 | __u64 gid = 0xFFFFFFFFFFFFFFFFULL; | 1202 | __u64 gid = 0xFFFFFFFFFFFFFFFFULL; |
@@ -1326,15 +1333,23 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
1326 | else if (attrs->ia_valid & ATTR_MODE) { | 1333 | else if (attrs->ia_valid & ATTR_MODE) { |
1327 | rc = 0; | 1334 | rc = 0; |
1328 | if ((mode & S_IWUGO) == 0) /* not writeable */ { | 1335 | if ((mode & S_IWUGO) == 0) /* not writeable */ { |
1329 | if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) | 1336 | if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) { |
1337 | set_dosattr = TRUE; | ||
1330 | time_buf.Attributes = | 1338 | time_buf.Attributes = |
1331 | cpu_to_le32(cifsInode->cifsAttrs | | 1339 | cpu_to_le32(cifsInode->cifsAttrs | |
1332 | ATTR_READONLY); | 1340 | ATTR_READONLY); |
1341 | } | ||
1333 | } else if ((mode & S_IWUGO) == S_IWUGO) { | 1342 | } else if ((mode & S_IWUGO) == S_IWUGO) { |
1334 | if (cifsInode->cifsAttrs & ATTR_READONLY) | 1343 | if (cifsInode->cifsAttrs & ATTR_READONLY) { |
1344 | set_dosattr = TRUE; | ||
1335 | time_buf.Attributes = | 1345 | time_buf.Attributes = |
1336 | cpu_to_le32(cifsInode->cifsAttrs & | 1346 | cpu_to_le32(cifsInode->cifsAttrs & |
1337 | (~ATTR_READONLY)); | 1347 | (~ATTR_READONLY)); |
1348 | /* Windows ignores set to zero */ | ||
1349 | if(time_buf.Attributes == 0) | ||
1350 | time_buf.Attributes |= | ||
1351 | cpu_to_le32(ATTR_NORMAL); | ||
1352 | } | ||
1338 | } | 1353 | } |
1339 | /* BB to be implemented - | 1354 | /* BB to be implemented - |
1340 | via Windows security descriptors or streams */ | 1355 | via Windows security descriptors or streams */ |
@@ -1372,7 +1387,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
1372 | } else | 1387 | } else |
1373 | time_buf.ChangeTime = 0; | 1388 | time_buf.ChangeTime = 0; |
1374 | 1389 | ||
1375 | if (set_time || time_buf.Attributes) { | 1390 | if (set_time || set_dosattr) { |
1376 | time_buf.CreationTime = 0; /* do not change */ | 1391 | time_buf.CreationTime = 0; /* do not change */ |
1377 | /* In the future we should experiment - try setting timestamps | 1392 | /* In the future we should experiment - try setting timestamps |
1378 | via Handle (SetFileInfo) instead of by path */ | 1393 | via Handle (SetFileInfo) instead of by path */ |
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 44cfb52879..2a374d5215 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -219,6 +219,10 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, | |||
219 | tmp_inode->i_mode |= S_IFREG; | 219 | tmp_inode->i_mode |= S_IFREG; |
220 | if (attr & ATTR_READONLY) | 220 | if (attr & ATTR_READONLY) |
221 | tmp_inode->i_mode &= ~(S_IWUGO); | 221 | tmp_inode->i_mode &= ~(S_IWUGO); |
222 | else if ((tmp_inode->i_mode & S_IWUGO) == 0) | ||
223 | /* the ATTR_READONLY flag may have been changed on */ | ||
224 | /* server -- set any w bits allowed by mnt_file_mode */ | ||
225 | tmp_inode->i_mode |= (S_IWUGO & cifs_sb->mnt_file_mode); | ||
222 | } /* could add code here - to validate if device or weird share type? */ | 226 | } /* could add code here - to validate if device or weird share type? */ |
223 | 227 | ||
224 | /* can not fill in nlink here as in qpathinfo version and Unx search */ | 228 | /* can not fill in nlink here as in qpathinfo version and Unx search */ |
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c index 34750d5e4f..5e6e37e58f 100644 --- a/fs/configfs/dir.c +++ b/fs/configfs/dir.c | |||
@@ -1141,25 +1141,22 @@ int configfs_register_subsystem(struct configfs_subsystem *subsys) | |||
1141 | 1141 | ||
1142 | err = -ENOMEM; | 1142 | err = -ENOMEM; |
1143 | dentry = d_alloc(configfs_sb->s_root, &name); | 1143 | dentry = d_alloc(configfs_sb->s_root, &name); |
1144 | if (!dentry) | 1144 | if (dentry) { |
1145 | goto out_release; | 1145 | d_add(dentry, NULL); |
1146 | |||
1147 | d_add(dentry, NULL); | ||
1148 | 1146 | ||
1149 | err = configfs_attach_group(sd->s_element, &group->cg_item, | 1147 | err = configfs_attach_group(sd->s_element, &group->cg_item, |
1150 | dentry); | 1148 | dentry); |
1151 | if (!err) | 1149 | if (err) { |
1152 | dentry = NULL; | 1150 | d_delete(dentry); |
1153 | else | 1151 | dput(dentry); |
1154 | d_delete(dentry); | 1152 | } |
1153 | } | ||
1155 | 1154 | ||
1156 | mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex); | 1155 | mutex_unlock(&configfs_sb->s_root->d_inode->i_mutex); |
1157 | 1156 | ||
1158 | if (dentry) { | 1157 | if (err) { |
1159 | dput(dentry); | 1158 | unlink_group(group); |
1160 | out_release: | 1159 | configfs_release_fs(); |
1161 | unlink_group(group); | ||
1162 | configfs_release_fs(); | ||
1163 | } | 1160 | } |
1164 | 1161 | ||
1165 | return err; | 1162 | return err; |
diff --git a/fs/ecryptfs/dentry.c b/fs/ecryptfs/dentry.c index 329efcd3d8..cb20b96441 100644 --- a/fs/ecryptfs/dentry.c +++ b/fs/ecryptfs/dentry.c | |||
@@ -78,18 +78,13 @@ struct kmem_cache *ecryptfs_dentry_info_cache; | |||
78 | */ | 78 | */ |
79 | static void ecryptfs_d_release(struct dentry *dentry) | 79 | static void ecryptfs_d_release(struct dentry *dentry) |
80 | { | 80 | { |
81 | struct dentry *lower_dentry; | 81 | if (ecryptfs_dentry_to_private(dentry)) { |
82 | 82 | if (ecryptfs_dentry_to_lower(dentry)) { | |
83 | lower_dentry = ecryptfs_dentry_to_lower(dentry); | 83 | mntput(ecryptfs_dentry_to_lower_mnt(dentry)); |
84 | if (ecryptfs_dentry_to_private(dentry)) | 84 | dput(ecryptfs_dentry_to_lower(dentry)); |
85 | } | ||
85 | kmem_cache_free(ecryptfs_dentry_info_cache, | 86 | kmem_cache_free(ecryptfs_dentry_info_cache, |
86 | ecryptfs_dentry_to_private(dentry)); | 87 | ecryptfs_dentry_to_private(dentry)); |
87 | if (lower_dentry) { | ||
88 | struct vfsmount *lower_mnt = | ||
89 | ecryptfs_dentry_to_lower_mnt(dentry); | ||
90 | |||
91 | mntput(lower_mnt); | ||
92 | dput(lower_dentry); | ||
93 | } | 88 | } |
94 | return; | 89 | return; |
95 | } | 90 | } |
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c index 12f7dda123..f58cbb2632 100644 --- a/fs/ext3/xattr.c +++ b/fs/ext3/xattr.c | |||
@@ -495,7 +495,8 @@ ext3_xattr_release_block(handle_t *handle, struct inode *inode, | |||
495 | BHDR(bh)->h_refcount = cpu_to_le32( | 495 | BHDR(bh)->h_refcount = cpu_to_le32( |
496 | le32_to_cpu(BHDR(bh)->h_refcount) - 1); | 496 | le32_to_cpu(BHDR(bh)->h_refcount) - 1); |
497 | error = ext3_journal_dirty_metadata(handle, bh); | 497 | error = ext3_journal_dirty_metadata(handle, bh); |
498 | handle->h_sync = 1; | 498 | if (IS_SYNC(inode)) |
499 | handle->h_sync = 1; | ||
499 | DQUOT_FREE_BLOCK(inode, 1); | 500 | DQUOT_FREE_BLOCK(inode, 1); |
500 | ea_bdebug(bh, "refcount now=%d; releasing", | 501 | ea_bdebug(bh, "refcount now=%d; releasing", |
501 | le32_to_cpu(BHDR(bh)->h_refcount)); | 502 | le32_to_cpu(BHDR(bh)->h_refcount)); |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index af53c02f47..93d046c85f 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -429,7 +429,8 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | |||
429 | int err; | 429 | int err; |
430 | 430 | ||
431 | /* Flush out writes to the server in order to update c/mtime */ | 431 | /* Flush out writes to the server in order to update c/mtime */ |
432 | nfs_sync_mapping_range(inode->i_mapping, 0, 0, FLUSH_NOCOMMIT); | 432 | if (S_ISREG(inode->i_mode)) |
433 | nfs_sync_mapping_range(inode->i_mapping, 0, 0, FLUSH_NOCOMMIT); | ||
433 | 434 | ||
434 | /* | 435 | /* |
435 | * We may force a getattr if the user cares about atime. | 436 | * We may force a getattr if the user cares about atime. |
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index bb516a2cfb..f1eae44b9a 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -151,10 +151,10 @@ int __init register_nfs_fs(void) | |||
151 | if (ret < 0) | 151 | if (ret < 0) |
152 | goto error_0; | 152 | goto error_0; |
153 | 153 | ||
154 | #ifdef CONFIG_NFS_V4 | ||
155 | ret = nfs_register_sysctl(); | 154 | ret = nfs_register_sysctl(); |
156 | if (ret < 0) | 155 | if (ret < 0) |
157 | goto error_1; | 156 | goto error_1; |
157 | #ifdef CONFIG_NFS_V4 | ||
158 | ret = register_filesystem(&nfs4_fs_type); | 158 | ret = register_filesystem(&nfs4_fs_type); |
159 | if (ret < 0) | 159 | if (ret < 0) |
160 | goto error_2; | 160 | goto error_2; |
@@ -165,9 +165,9 @@ int __init register_nfs_fs(void) | |||
165 | #ifdef CONFIG_NFS_V4 | 165 | #ifdef CONFIG_NFS_V4 |
166 | error_2: | 166 | error_2: |
167 | nfs_unregister_sysctl(); | 167 | nfs_unregister_sysctl(); |
168 | #endif | ||
168 | error_1: | 169 | error_1: |
169 | unregister_filesystem(&nfs_fs_type); | 170 | unregister_filesystem(&nfs_fs_type); |
170 | #endif | ||
171 | error_0: | 171 | error_0: |
172 | return ret; | 172 | return ret; |
173 | } | 173 | } |
diff --git a/fs/nfs/sysctl.c b/fs/nfs/sysctl.c index fcdcafbb32..b62481daba 100644 --- a/fs/nfs/sysctl.c +++ b/fs/nfs/sysctl.c | |||
@@ -50,6 +50,14 @@ static ctl_table nfs_cb_sysctls[] = { | |||
50 | .proc_handler = &proc_dointvec_jiffies, | 50 | .proc_handler = &proc_dointvec_jiffies, |
51 | .strategy = &sysctl_jiffies, | 51 | .strategy = &sysctl_jiffies, |
52 | }, | 52 | }, |
53 | { | ||
54 | .ctl_name = CTL_UNNUMBERED, | ||
55 | .procname = "nfs_congestion_kb", | ||
56 | .data = &nfs_congestion_kb, | ||
57 | .maxlen = sizeof(nfs_congestion_kb), | ||
58 | .mode = 0644, | ||
59 | .proc_handler = &proc_dointvec, | ||
60 | }, | ||
53 | { .ctl_name = 0 } | 61 | { .ctl_name = 0 } |
54 | }; | 62 | }; |
55 | 63 | ||
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index febdade916..2867e6b709 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/pagemap.h> | 12 | #include <linux/pagemap.h> |
13 | #include <linux/file.h> | 13 | #include <linux/file.h> |
14 | #include <linux/writeback.h> | 14 | #include <linux/writeback.h> |
15 | #include <linux/swap.h> | ||
15 | 16 | ||
16 | #include <linux/sunrpc/clnt.h> | 17 | #include <linux/sunrpc/clnt.h> |
17 | #include <linux/nfs_fs.h> | 18 | #include <linux/nfs_fs.h> |
@@ -38,7 +39,6 @@ static struct nfs_page * nfs_update_request(struct nfs_open_context*, | |||
38 | struct page *, | 39 | struct page *, |
39 | unsigned int, unsigned int); | 40 | unsigned int, unsigned int); |
40 | static void nfs_mark_request_dirty(struct nfs_page *req); | 41 | static void nfs_mark_request_dirty(struct nfs_page *req); |
41 | static int nfs_wait_on_write_congestion(struct address_space *, int); | ||
42 | static long nfs_flush_mapping(struct address_space *mapping, struct writeback_control *wbc, int how); | 42 | static long nfs_flush_mapping(struct address_space *mapping, struct writeback_control *wbc, int how); |
43 | static const struct rpc_call_ops nfs_write_partial_ops; | 43 | static const struct rpc_call_ops nfs_write_partial_ops; |
44 | static const struct rpc_call_ops nfs_write_full_ops; | 44 | static const struct rpc_call_ops nfs_write_full_ops; |
@@ -48,8 +48,6 @@ static struct kmem_cache *nfs_wdata_cachep; | |||
48 | static mempool_t *nfs_wdata_mempool; | 48 | static mempool_t *nfs_wdata_mempool; |
49 | static mempool_t *nfs_commit_mempool; | 49 | static mempool_t *nfs_commit_mempool; |
50 | 50 | ||
51 | static DECLARE_WAIT_QUEUE_HEAD(nfs_write_congestion); | ||
52 | |||
53 | struct nfs_write_data *nfs_commit_alloc(void) | 51 | struct nfs_write_data *nfs_commit_alloc(void) |
54 | { | 52 | { |
55 | struct nfs_write_data *p = mempool_alloc(nfs_commit_mempool, GFP_NOFS); | 53 | struct nfs_write_data *p = mempool_alloc(nfs_commit_mempool, GFP_NOFS); |
@@ -211,6 +209,40 @@ static int wb_priority(struct writeback_control *wbc) | |||
211 | } | 209 | } |
212 | 210 | ||
213 | /* | 211 | /* |
212 | * NFS congestion control | ||
213 | */ | ||
214 | |||
215 | int nfs_congestion_kb; | ||
216 | |||
217 | #define NFS_CONGESTION_ON_THRESH (nfs_congestion_kb >> (PAGE_SHIFT-10)) | ||
218 | #define NFS_CONGESTION_OFF_THRESH \ | ||
219 | (NFS_CONGESTION_ON_THRESH - (NFS_CONGESTION_ON_THRESH >> 2)) | ||
220 | |||
221 | static void nfs_set_page_writeback(struct page *page) | ||
222 | { | ||
223 | if (!test_set_page_writeback(page)) { | ||
224 | struct inode *inode = page->mapping->host; | ||
225 | struct nfs_server *nfss = NFS_SERVER(inode); | ||
226 | |||
227 | if (atomic_inc_return(&nfss->writeback) > | ||
228 | NFS_CONGESTION_ON_THRESH) | ||
229 | set_bdi_congested(&nfss->backing_dev_info, WRITE); | ||
230 | } | ||
231 | } | ||
232 | |||
233 | static void nfs_end_page_writeback(struct page *page) | ||
234 | { | ||
235 | struct inode *inode = page->mapping->host; | ||
236 | struct nfs_server *nfss = NFS_SERVER(inode); | ||
237 | |||
238 | end_page_writeback(page); | ||
239 | if (atomic_dec_return(&nfss->writeback) < NFS_CONGESTION_OFF_THRESH) { | ||
240 | clear_bdi_congested(&nfss->backing_dev_info, WRITE); | ||
241 | congestion_end(WRITE); | ||
242 | } | ||
243 | } | ||
244 | |||
245 | /* | ||
214 | * Find an associated nfs write request, and prepare to flush it out | 246 | * Find an associated nfs write request, and prepare to flush it out |
215 | * Returns 1 if there was no write request, or if the request was | 247 | * Returns 1 if there was no write request, or if the request was |
216 | * already tagged by nfs_set_page_dirty.Returns 0 if the request | 248 | * already tagged by nfs_set_page_dirty.Returns 0 if the request |
@@ -247,7 +279,7 @@ static int nfs_page_mark_flush(struct page *page) | |||
247 | spin_unlock(req_lock); | 279 | spin_unlock(req_lock); |
248 | if (test_and_set_bit(PG_FLUSHING, &req->wb_flags) == 0) { | 280 | if (test_and_set_bit(PG_FLUSHING, &req->wb_flags) == 0) { |
249 | nfs_mark_request_dirty(req); | 281 | nfs_mark_request_dirty(req); |
250 | set_page_writeback(page); | 282 | nfs_set_page_writeback(page); |
251 | } | 283 | } |
252 | ret = test_bit(PG_NEED_FLUSH, &req->wb_flags); | 284 | ret = test_bit(PG_NEED_FLUSH, &req->wb_flags); |
253 | nfs_unlock_request(req); | 285 | nfs_unlock_request(req); |
@@ -302,13 +334,8 @@ int nfs_writepage(struct page *page, struct writeback_control *wbc) | |||
302 | return err; | 334 | return err; |
303 | } | 335 | } |
304 | 336 | ||
305 | /* | ||
306 | * Note: causes nfs_update_request() to block on the assumption | ||
307 | * that the writeback is generated due to memory pressure. | ||
308 | */ | ||
309 | int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc) | 337 | int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc) |
310 | { | 338 | { |
311 | struct backing_dev_info *bdi = mapping->backing_dev_info; | ||
312 | struct inode *inode = mapping->host; | 339 | struct inode *inode = mapping->host; |
313 | int err; | 340 | int err; |
314 | 341 | ||
@@ -317,20 +344,12 @@ int nfs_writepages(struct address_space *mapping, struct writeback_control *wbc) | |||
317 | err = generic_writepages(mapping, wbc); | 344 | err = generic_writepages(mapping, wbc); |
318 | if (err) | 345 | if (err) |
319 | return err; | 346 | return err; |
320 | while (test_and_set_bit(BDI_write_congested, &bdi->state) != 0) { | ||
321 | if (wbc->nonblocking) | ||
322 | return 0; | ||
323 | nfs_wait_on_write_congestion(mapping, 0); | ||
324 | } | ||
325 | err = nfs_flush_mapping(mapping, wbc, wb_priority(wbc)); | 347 | err = nfs_flush_mapping(mapping, wbc, wb_priority(wbc)); |
326 | if (err < 0) | 348 | if (err < 0) |
327 | goto out; | 349 | goto out; |
328 | nfs_add_stats(inode, NFSIOS_WRITEPAGES, err); | 350 | nfs_add_stats(inode, NFSIOS_WRITEPAGES, err); |
329 | err = 0; | 351 | err = 0; |
330 | out: | 352 | out: |
331 | clear_bit(BDI_write_congested, &bdi->state); | ||
332 | wake_up_all(&nfs_write_congestion); | ||
333 | congestion_end(WRITE); | ||
334 | return err; | 353 | return err; |
335 | } | 354 | } |
336 | 355 | ||
@@ -360,7 +379,7 @@ static int nfs_inode_add_request(struct inode *inode, struct nfs_page *req) | |||
360 | } | 379 | } |
361 | 380 | ||
362 | /* | 381 | /* |
363 | * Insert a write request into an inode | 382 | * Remove a write request from an inode |
364 | */ | 383 | */ |
365 | static void nfs_inode_remove_request(struct nfs_page *req) | 384 | static void nfs_inode_remove_request(struct nfs_page *req) |
366 | { | 385 | { |
@@ -531,10 +550,10 @@ static inline int nfs_scan_commit(struct inode *inode, struct list_head *dst, un | |||
531 | } | 550 | } |
532 | #endif | 551 | #endif |
533 | 552 | ||
534 | static int nfs_wait_on_write_congestion(struct address_space *mapping, int intr) | 553 | static int nfs_wait_on_write_congestion(struct address_space *mapping) |
535 | { | 554 | { |
555 | struct inode *inode = mapping->host; | ||
536 | struct backing_dev_info *bdi = mapping->backing_dev_info; | 556 | struct backing_dev_info *bdi = mapping->backing_dev_info; |
537 | DEFINE_WAIT(wait); | ||
538 | int ret = 0; | 557 | int ret = 0; |
539 | 558 | ||
540 | might_sleep(); | 559 | might_sleep(); |
@@ -542,31 +561,23 @@ static int nfs_wait_on_write_congestion(struct address_space *mapping, int intr) | |||
542 | if (!bdi_write_congested(bdi)) | 561 | if (!bdi_write_congested(bdi)) |
543 | return 0; | 562 | return 0; |
544 | 563 | ||
545 | nfs_inc_stats(mapping->host, NFSIOS_CONGESTIONWAIT); | 564 | nfs_inc_stats(inode, NFSIOS_CONGESTIONWAIT); |
546 | 565 | ||
547 | if (intr) { | 566 | do { |
548 | struct rpc_clnt *clnt = NFS_CLIENT(mapping->host); | 567 | struct rpc_clnt *clnt = NFS_CLIENT(inode); |
549 | sigset_t oldset; | 568 | sigset_t oldset; |
550 | 569 | ||
551 | rpc_clnt_sigmask(clnt, &oldset); | 570 | rpc_clnt_sigmask(clnt, &oldset); |
552 | prepare_to_wait(&nfs_write_congestion, &wait, TASK_INTERRUPTIBLE); | 571 | ret = congestion_wait_interruptible(WRITE, HZ/10); |
553 | if (bdi_write_congested(bdi)) { | ||
554 | if (signalled()) | ||
555 | ret = -ERESTARTSYS; | ||
556 | else | ||
557 | schedule(); | ||
558 | } | ||
559 | rpc_clnt_sigunmask(clnt, &oldset); | 572 | rpc_clnt_sigunmask(clnt, &oldset); |
560 | } else { | 573 | if (ret == -ERESTARTSYS) |
561 | prepare_to_wait(&nfs_write_congestion, &wait, TASK_UNINTERRUPTIBLE); | 574 | break; |
562 | if (bdi_write_congested(bdi)) | 575 | ret = 0; |
563 | schedule(); | 576 | } while (bdi_write_congested(bdi)); |
564 | } | 577 | |
565 | finish_wait(&nfs_write_congestion, &wait); | ||
566 | return ret; | 578 | return ret; |
567 | } | 579 | } |
568 | 580 | ||
569 | |||
570 | /* | 581 | /* |
571 | * Try to update any existing write request, or create one if there is none. | 582 | * Try to update any existing write request, or create one if there is none. |
572 | * In order to match, the request's credentials must match those of | 583 | * In order to match, the request's credentials must match those of |
@@ -577,14 +588,15 @@ static int nfs_wait_on_write_congestion(struct address_space *mapping, int intr) | |||
577 | static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, | 588 | static struct nfs_page * nfs_update_request(struct nfs_open_context* ctx, |
578 | struct page *page, unsigned int offset, unsigned int bytes) | 589 | struct page *page, unsigned int offset, unsigned int bytes) |
579 | { | 590 | { |
580 | struct inode *inode = page->mapping->host; | 591 | struct address_space *mapping = page->mapping; |
592 | struct inode *inode = mapping->host; | ||
581 | struct nfs_inode *nfsi = NFS_I(inode); | 593 | struct nfs_inode *nfsi = NFS_I(inode); |
582 | struct nfs_page *req, *new = NULL; | 594 | struct nfs_page *req, *new = NULL; |
583 | unsigned long rqend, end; | 595 | unsigned long rqend, end; |
584 | 596 | ||
585 | end = offset + bytes; | 597 | end = offset + bytes; |
586 | 598 | ||
587 | if (nfs_wait_on_write_congestion(page->mapping, NFS_SERVER(inode)->flags & NFS_MOUNT_INTR)) | 599 | if (nfs_wait_on_write_congestion(mapping)) |
588 | return ERR_PTR(-ERESTARTSYS); | 600 | return ERR_PTR(-ERESTARTSYS); |
589 | for (;;) { | 601 | for (;;) { |
590 | /* Loop over all inode entries and see if we find | 602 | /* Loop over all inode entries and see if we find |
@@ -727,7 +739,7 @@ int nfs_updatepage(struct file *file, struct page *page, | |||
727 | 739 | ||
728 | static void nfs_writepage_release(struct nfs_page *req) | 740 | static void nfs_writepage_release(struct nfs_page *req) |
729 | { | 741 | { |
730 | end_page_writeback(req->wb_page); | 742 | nfs_end_page_writeback(req->wb_page); |
731 | 743 | ||
732 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | 744 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) |
733 | if (!PageError(req->wb_page)) { | 745 | if (!PageError(req->wb_page)) { |
@@ -1042,12 +1054,12 @@ static void nfs_writeback_done_full(struct rpc_task *task, void *calldata) | |||
1042 | if (task->tk_status < 0) { | 1054 | if (task->tk_status < 0) { |
1043 | nfs_set_pageerror(page); | 1055 | nfs_set_pageerror(page); |
1044 | req->wb_context->error = task->tk_status; | 1056 | req->wb_context->error = task->tk_status; |
1045 | end_page_writeback(page); | 1057 | nfs_end_page_writeback(page); |
1046 | nfs_inode_remove_request(req); | 1058 | nfs_inode_remove_request(req); |
1047 | dprintk(", error = %d\n", task->tk_status); | 1059 | dprintk(", error = %d\n", task->tk_status); |
1048 | goto next; | 1060 | goto next; |
1049 | } | 1061 | } |
1050 | end_page_writeback(page); | 1062 | nfs_end_page_writeback(page); |
1051 | 1063 | ||
1052 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | 1064 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) |
1053 | if (data->args.stable != NFS_UNSTABLE || data->verf.committed == NFS_FILE_SYNC) { | 1065 | if (data->args.stable != NFS_UNSTABLE || data->verf.committed == NFS_FILE_SYNC) { |
@@ -1514,6 +1526,26 @@ int __init nfs_init_writepagecache(void) | |||
1514 | if (nfs_commit_mempool == NULL) | 1526 | if (nfs_commit_mempool == NULL) |
1515 | return -ENOMEM; | 1527 | return -ENOMEM; |
1516 | 1528 | ||
1529 | /* | ||
1530 | * NFS congestion size, scale with available memory. | ||
1531 | * | ||
1532 | * 64MB: 8192k | ||
1533 | * 128MB: 11585k | ||
1534 | * 256MB: 16384k | ||
1535 | * 512MB: 23170k | ||
1536 | * 1GB: 32768k | ||
1537 | * 2GB: 46340k | ||
1538 | * 4GB: 65536k | ||
1539 | * 8GB: 92681k | ||
1540 | * 16GB: 131072k | ||
1541 | * | ||
1542 | * This allows larger machines to have larger/more transfers. | ||
1543 | * Limit the default to 256M | ||
1544 | */ | ||
1545 | nfs_congestion_kb = (16*int_sqrt(totalram_pages)) << (PAGE_SHIFT-10); | ||
1546 | if (nfs_congestion_kb > 256*1024) | ||
1547 | nfs_congestion_kb = 256*1024; | ||
1548 | |||
1517 | return 0; | 1549 | return 0; |
1518 | } | 1550 | } |
1519 | 1551 | ||
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 6f677988c7..7e4bb0af24 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c | |||
@@ -859,8 +859,8 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp, | |||
859 | #define NFS3_ENTRY_BAGGAGE (2 + 1 + 2 + 1) | 859 | #define NFS3_ENTRY_BAGGAGE (2 + 1 + 2 + 1) |
860 | #define NFS3_ENTRYPLUS_BAGGAGE (1 + 21 + 1 + (NFS3_FHSIZE >> 2)) | 860 | #define NFS3_ENTRYPLUS_BAGGAGE (1 + 21 + 1 + (NFS3_FHSIZE >> 2)) |
861 | static int | 861 | static int |
862 | encode_entry(struct readdir_cd *ccd, const char *name, | 862 | encode_entry(struct readdir_cd *ccd, const char *name, int namlen, |
863 | int namlen, off_t offset, ino_t ino, unsigned int d_type, int plus) | 863 | loff_t offset, ino_t ino, unsigned int d_type, int plus) |
864 | { | 864 | { |
865 | struct nfsd3_readdirres *cd = container_of(ccd, struct nfsd3_readdirres, | 865 | struct nfsd3_readdirres *cd = container_of(ccd, struct nfsd3_readdirres, |
866 | common); | 866 | common); |
@@ -880,7 +880,7 @@ encode_entry(struct readdir_cd *ccd, const char *name, | |||
880 | *cd->offset1 = htonl(offset64 & 0xffffffff); | 880 | *cd->offset1 = htonl(offset64 & 0xffffffff); |
881 | cd->offset1 = NULL; | 881 | cd->offset1 = NULL; |
882 | } else { | 882 | } else { |
883 | xdr_encode_hyper(cd->offset, (u64) offset); | 883 | xdr_encode_hyper(cd->offset, offset64); |
884 | } | 884 | } |
885 | } | 885 | } |
886 | 886 | ||
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index 832673b145..673a53c014 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c | |||
@@ -228,7 +228,7 @@ _posix_to_nfsv4_one(struct posix_acl *pacl, struct nfs4_acl *acl, | |||
228 | struct posix_acl_summary pas; | 228 | struct posix_acl_summary pas; |
229 | unsigned short deny; | 229 | unsigned short deny; |
230 | int eflag = ((flags & NFS4_ACL_TYPE_DEFAULT) ? | 230 | int eflag = ((flags & NFS4_ACL_TYPE_DEFAULT) ? |
231 | NFS4_INHERITANCE_FLAGS : 0); | 231 | NFS4_INHERITANCE_FLAGS | NFS4_ACE_INHERIT_ONLY_ACE : 0); |
232 | 232 | ||
233 | BUG_ON(pacl->a_count < 3); | 233 | BUG_ON(pacl->a_count < 3); |
234 | summarize_posix_acl(pacl, &pas); | 234 | summarize_posix_acl(pacl, &pas); |
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 9e40679992..af360705e5 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -750,9 +750,8 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
750 | status = nfserr_clid_inuse; | 750 | status = nfserr_clid_inuse; |
751 | if (!cmp_creds(&conf->cl_cred, &rqstp->rq_cred) | 751 | if (!cmp_creds(&conf->cl_cred, &rqstp->rq_cred) |
752 | || conf->cl_addr != sin->sin_addr.s_addr) { | 752 | || conf->cl_addr != sin->sin_addr.s_addr) { |
753 | printk("NFSD: setclientid: string in use by client" | 753 | dprintk("NFSD: setclientid: string in use by client" |
754 | "(clientid %08x/%08x)\n", | 754 | "at %u.%u.%u.%u\n", NIPQUAD(conf->cl_addr)); |
755 | conf->cl_clientid.cl_boot, conf->cl_clientid.cl_id); | ||
756 | goto out; | 755 | goto out; |
757 | } | 756 | } |
758 | } | 757 | } |
@@ -3261,7 +3260,6 @@ __nfs4_state_shutdown(void) | |||
3261 | unhash_delegation(dp); | 3260 | unhash_delegation(dp); |
3262 | } | 3261 | } |
3263 | 3262 | ||
3264 | cancel_delayed_work(&laundromat_work); | ||
3265 | nfsd4_shutdown_recdir(); | 3263 | nfsd4_shutdown_recdir(); |
3266 | nfs4_init = 0; | 3264 | nfs4_init = 0; |
3267 | } | 3265 | } |
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index c2660cbfcd..8d995bcef8 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include <linux/stat.h> | 17 | #include <linux/stat.h> |
18 | #include <linux/dcache.h> | 18 | #include <linux/dcache.h> |
19 | #include <linux/mount.h> | 19 | #include <linux/mount.h> |
20 | #include <asm/pgtable.h> | ||
21 | 20 | ||
22 | #include <linux/sunrpc/clnt.h> | 21 | #include <linux/sunrpc/clnt.h> |
23 | #include <linux/sunrpc/svc.h> | 22 | #include <linux/sunrpc/svc.h> |
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index 93628b02ef..875c114438 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
@@ -614,6 +614,27 @@ static void ocfs2_dio_end_io(struct kiocb *iocb, | |||
614 | ocfs2_rw_unlock(inode, 0); | 614 | ocfs2_rw_unlock(inode, 0); |
615 | } | 615 | } |
616 | 616 | ||
617 | /* | ||
618 | * ocfs2_invalidatepage() and ocfs2_releasepage() are shamelessly stolen | ||
619 | * from ext3. PageChecked() bits have been removed as OCFS2 does not | ||
620 | * do journalled data. | ||
621 | */ | ||
622 | static void ocfs2_invalidatepage(struct page *page, unsigned long offset) | ||
623 | { | ||
624 | journal_t *journal = OCFS2_SB(page->mapping->host->i_sb)->journal->j_journal; | ||
625 | |||
626 | journal_invalidatepage(journal, page, offset); | ||
627 | } | ||
628 | |||
629 | static int ocfs2_releasepage(struct page *page, gfp_t wait) | ||
630 | { | ||
631 | journal_t *journal = OCFS2_SB(page->mapping->host->i_sb)->journal->j_journal; | ||
632 | |||
633 | if (!page_has_buffers(page)) | ||
634 | return 0; | ||
635 | return journal_try_to_free_buffers(journal, page, wait); | ||
636 | } | ||
637 | |||
617 | static ssize_t ocfs2_direct_IO(int rw, | 638 | static ssize_t ocfs2_direct_IO(int rw, |
618 | struct kiocb *iocb, | 639 | struct kiocb *iocb, |
619 | const struct iovec *iov, | 640 | const struct iovec *iov, |
@@ -661,5 +682,8 @@ const struct address_space_operations ocfs2_aops = { | |||
661 | .commit_write = ocfs2_commit_write, | 682 | .commit_write = ocfs2_commit_write, |
662 | .bmap = ocfs2_bmap, | 683 | .bmap = ocfs2_bmap, |
663 | .sync_page = block_sync_page, | 684 | .sync_page = block_sync_page, |
664 | .direct_IO = ocfs2_direct_IO | 685 | .direct_IO = ocfs2_direct_IO, |
686 | .invalidatepage = ocfs2_invalidatepage, | ||
687 | .releasepage = ocfs2_releasepage, | ||
688 | .migratepage = buffer_migrate_page, | ||
665 | }; | 689 | }; |
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index 5a9779bb92..eba282da50 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c | |||
@@ -1234,6 +1234,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, | |||
1234 | const char *page, | 1234 | const char *page, |
1235 | size_t count) | 1235 | size_t count) |
1236 | { | 1236 | { |
1237 | struct task_struct *hb_task; | ||
1237 | long fd; | 1238 | long fd; |
1238 | int sectsize; | 1239 | int sectsize; |
1239 | char *p = (char *)page; | 1240 | char *p = (char *)page; |
@@ -1319,20 +1320,28 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, | |||
1319 | */ | 1320 | */ |
1320 | atomic_set(®->hr_steady_iterations, O2HB_LIVE_THRESHOLD + 1); | 1321 | atomic_set(®->hr_steady_iterations, O2HB_LIVE_THRESHOLD + 1); |
1321 | 1322 | ||
1322 | reg->hr_task = kthread_run(o2hb_thread, reg, "o2hb-%s", | 1323 | hb_task = kthread_run(o2hb_thread, reg, "o2hb-%s", |
1323 | reg->hr_item.ci_name); | 1324 | reg->hr_item.ci_name); |
1324 | if (IS_ERR(reg->hr_task)) { | 1325 | if (IS_ERR(hb_task)) { |
1325 | ret = PTR_ERR(reg->hr_task); | 1326 | ret = PTR_ERR(hb_task); |
1326 | mlog_errno(ret); | 1327 | mlog_errno(ret); |
1327 | reg->hr_task = NULL; | ||
1328 | goto out; | 1328 | goto out; |
1329 | } | 1329 | } |
1330 | 1330 | ||
1331 | spin_lock(&o2hb_live_lock); | ||
1332 | reg->hr_task = hb_task; | ||
1333 | spin_unlock(&o2hb_live_lock); | ||
1334 | |||
1331 | ret = wait_event_interruptible(o2hb_steady_queue, | 1335 | ret = wait_event_interruptible(o2hb_steady_queue, |
1332 | atomic_read(®->hr_steady_iterations) == 0); | 1336 | atomic_read(®->hr_steady_iterations) == 0); |
1333 | if (ret) { | 1337 | if (ret) { |
1334 | kthread_stop(reg->hr_task); | 1338 | spin_lock(&o2hb_live_lock); |
1339 | hb_task = reg->hr_task; | ||
1335 | reg->hr_task = NULL; | 1340 | reg->hr_task = NULL; |
1341 | spin_unlock(&o2hb_live_lock); | ||
1342 | |||
1343 | if (hb_task) | ||
1344 | kthread_stop(hb_task); | ||
1336 | goto out; | 1345 | goto out; |
1337 | } | 1346 | } |
1338 | 1347 | ||
@@ -1354,10 +1363,17 @@ out: | |||
1354 | static ssize_t o2hb_region_pid_read(struct o2hb_region *reg, | 1363 | static ssize_t o2hb_region_pid_read(struct o2hb_region *reg, |
1355 | char *page) | 1364 | char *page) |
1356 | { | 1365 | { |
1357 | if (!reg->hr_task) | 1366 | pid_t pid = 0; |
1367 | |||
1368 | spin_lock(&o2hb_live_lock); | ||
1369 | if (reg->hr_task) | ||
1370 | pid = reg->hr_task->pid; | ||
1371 | spin_unlock(&o2hb_live_lock); | ||
1372 | |||
1373 | if (!pid) | ||
1358 | return 0; | 1374 | return 0; |
1359 | 1375 | ||
1360 | return sprintf(page, "%u\n", reg->hr_task->pid); | 1376 | return sprintf(page, "%u\n", pid); |
1361 | } | 1377 | } |
1362 | 1378 | ||
1363 | struct o2hb_region_attribute { | 1379 | struct o2hb_region_attribute { |
@@ -1495,13 +1511,17 @@ out: | |||
1495 | static void o2hb_heartbeat_group_drop_item(struct config_group *group, | 1511 | static void o2hb_heartbeat_group_drop_item(struct config_group *group, |
1496 | struct config_item *item) | 1512 | struct config_item *item) |
1497 | { | 1513 | { |
1514 | struct task_struct *hb_task; | ||
1498 | struct o2hb_region *reg = to_o2hb_region(item); | 1515 | struct o2hb_region *reg = to_o2hb_region(item); |
1499 | 1516 | ||
1500 | /* stop the thread when the user removes the region dir */ | 1517 | /* stop the thread when the user removes the region dir */ |
1501 | if (reg->hr_task) { | 1518 | spin_lock(&o2hb_live_lock); |
1502 | kthread_stop(reg->hr_task); | 1519 | hb_task = reg->hr_task; |
1503 | reg->hr_task = NULL; | 1520 | reg->hr_task = NULL; |
1504 | } | 1521 | spin_unlock(&o2hb_live_lock); |
1522 | |||
1523 | if (hb_task) | ||
1524 | kthread_stop(hb_task); | ||
1505 | 1525 | ||
1506 | config_item_put(item); | 1526 | config_item_put(item); |
1507 | } | 1527 | } |
@@ -1682,7 +1702,7 @@ out: | |||
1682 | } | 1702 | } |
1683 | EXPORT_SYMBOL_GPL(o2hb_register_callback); | 1703 | EXPORT_SYMBOL_GPL(o2hb_register_callback); |
1684 | 1704 | ||
1685 | int o2hb_unregister_callback(struct o2hb_callback_func *hc) | 1705 | void o2hb_unregister_callback(struct o2hb_callback_func *hc) |
1686 | { | 1706 | { |
1687 | BUG_ON(hc->hc_magic != O2HB_CB_MAGIC); | 1707 | BUG_ON(hc->hc_magic != O2HB_CB_MAGIC); |
1688 | 1708 | ||
@@ -1690,15 +1710,13 @@ int o2hb_unregister_callback(struct o2hb_callback_func *hc) | |||
1690 | __builtin_return_address(0), hc); | 1710 | __builtin_return_address(0), hc); |
1691 | 1711 | ||
1692 | if (list_empty(&hc->hc_item)) | 1712 | if (list_empty(&hc->hc_item)) |
1693 | return 0; | 1713 | return; |
1694 | 1714 | ||
1695 | down_write(&o2hb_callback_sem); | 1715 | down_write(&o2hb_callback_sem); |
1696 | 1716 | ||
1697 | list_del_init(&hc->hc_item); | 1717 | list_del_init(&hc->hc_item); |
1698 | 1718 | ||
1699 | up_write(&o2hb_callback_sem); | 1719 | up_write(&o2hb_callback_sem); |
1700 | |||
1701 | return 0; | ||
1702 | } | 1720 | } |
1703 | EXPORT_SYMBOL_GPL(o2hb_unregister_callback); | 1721 | EXPORT_SYMBOL_GPL(o2hb_unregister_callback); |
1704 | 1722 | ||
diff --git a/fs/ocfs2/cluster/heartbeat.h b/fs/ocfs2/cluster/heartbeat.h index cac6223206..cc6d40b397 100644 --- a/fs/ocfs2/cluster/heartbeat.h +++ b/fs/ocfs2/cluster/heartbeat.h | |||
@@ -70,7 +70,7 @@ void o2hb_setup_callback(struct o2hb_callback_func *hc, | |||
70 | void *data, | 70 | void *data, |
71 | int priority); | 71 | int priority); |
72 | int o2hb_register_callback(struct o2hb_callback_func *hc); | 72 | int o2hb_register_callback(struct o2hb_callback_func *hc); |
73 | int o2hb_unregister_callback(struct o2hb_callback_func *hc); | 73 | void o2hb_unregister_callback(struct o2hb_callback_func *hc); |
74 | void o2hb_fill_node_map(unsigned long *map, | 74 | void o2hb_fill_node_map(unsigned long *map, |
75 | unsigned bytes); | 75 | unsigned bytes); |
76 | void o2hb_init(void); | 76 | void o2hb_init(void); |
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index 1718215fc0..69caf3e12f 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c | |||
@@ -1638,17 +1638,8 @@ static void o2net_hb_node_up_cb(struct o2nm_node *node, int node_num, | |||
1638 | 1638 | ||
1639 | void o2net_unregister_hb_callbacks(void) | 1639 | void o2net_unregister_hb_callbacks(void) |
1640 | { | 1640 | { |
1641 | int ret; | 1641 | o2hb_unregister_callback(&o2net_hb_up); |
1642 | 1642 | o2hb_unregister_callback(&o2net_hb_down); | |
1643 | ret = o2hb_unregister_callback(&o2net_hb_up); | ||
1644 | if (ret < 0) | ||
1645 | mlog(ML_ERROR, "Status return %d unregistering heartbeat up " | ||
1646 | "callback!\n", ret); | ||
1647 | |||
1648 | ret = o2hb_unregister_callback(&o2net_hb_down); | ||
1649 | if (ret < 0) | ||
1650 | mlog(ML_ERROR, "Status return %d unregistering heartbeat down " | ||
1651 | "callback!\n", ret); | ||
1652 | } | 1643 | } |
1653 | 1644 | ||
1654 | int o2net_register_hb_callbacks(void) | 1645 | int o2net_register_hb_callbacks(void) |
diff --git a/fs/ocfs2/dlm/dlmmaster.c b/fs/ocfs2/dlm/dlmmaster.c index 77e4e6169a..9229e04362 100644 --- a/fs/ocfs2/dlm/dlmmaster.c +++ b/fs/ocfs2/dlm/dlmmaster.c | |||
@@ -2730,14 +2730,17 @@ int dlm_empty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res) | |||
2730 | int ret; | 2730 | int ret; |
2731 | int lock_dropped = 0; | 2731 | int lock_dropped = 0; |
2732 | 2732 | ||
2733 | spin_lock(&res->spinlock); | ||
2733 | if (res->owner != dlm->node_num) { | 2734 | if (res->owner != dlm->node_num) { |
2734 | if (!__dlm_lockres_unused(res)) { | 2735 | if (!__dlm_lockres_unused(res)) { |
2735 | mlog(ML_ERROR, "%s:%.*s: this node is not master, " | 2736 | mlog(ML_ERROR, "%s:%.*s: this node is not master, " |
2736 | "trying to free this but locks remain\n", | 2737 | "trying to free this but locks remain\n", |
2737 | dlm->name, res->lockname.len, res->lockname.name); | 2738 | dlm->name, res->lockname.len, res->lockname.name); |
2738 | } | 2739 | } |
2740 | spin_unlock(&res->spinlock); | ||
2739 | goto leave; | 2741 | goto leave; |
2740 | } | 2742 | } |
2743 | spin_unlock(&res->spinlock); | ||
2741 | 2744 | ||
2742 | /* Wheee! Migrate lockres here! Will sleep so drop spinlock. */ | 2745 | /* Wheee! Migrate lockres here! Will sleep so drop spinlock. */ |
2743 | spin_unlock(&dlm->spinlock); | 2746 | spin_unlock(&dlm->spinlock); |
diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c index 8ffa0916eb..6421a8fae1 100644 --- a/fs/ocfs2/dlm/dlmthread.c +++ b/fs/ocfs2/dlm/dlmthread.c | |||
@@ -265,8 +265,10 @@ static void dlm_run_purge_list(struct dlm_ctxt *dlm, | |||
265 | /* This may drop and reacquire the dlm spinlock if it | 265 | /* This may drop and reacquire the dlm spinlock if it |
266 | * has to do migration. */ | 266 | * has to do migration. */ |
267 | mlog(0, "calling dlm_purge_lockres!\n"); | 267 | mlog(0, "calling dlm_purge_lockres!\n"); |
268 | dlm_lockres_get(lockres); | ||
268 | if (dlm_purge_lockres(dlm, lockres)) | 269 | if (dlm_purge_lockres(dlm, lockres)) |
269 | BUG(); | 270 | BUG(); |
271 | dlm_lockres_put(lockres); | ||
270 | mlog(0, "DONE calling dlm_purge_lockres!\n"); | 272 | mlog(0, "DONE calling dlm_purge_lockres!\n"); |
271 | 273 | ||
272 | /* Avoid adding any scheduling latencies */ | 274 | /* Avoid adding any scheduling latencies */ |
diff --git a/fs/ocfs2/heartbeat.c b/fs/ocfs2/heartbeat.c index 8fc52d6d0c..b25ef63781 100644 --- a/fs/ocfs2/heartbeat.c +++ b/fs/ocfs2/heartbeat.c | |||
@@ -164,8 +164,10 @@ int ocfs2_register_hb_callbacks(struct ocfs2_super *osb) | |||
164 | } | 164 | } |
165 | 165 | ||
166 | status = o2hb_register_callback(&osb->osb_hb_up); | 166 | status = o2hb_register_callback(&osb->osb_hb_up); |
167 | if (status < 0) | 167 | if (status < 0) { |
168 | mlog_errno(status); | 168 | mlog_errno(status); |
169 | o2hb_unregister_callback(&osb->osb_hb_down); | ||
170 | } | ||
169 | 171 | ||
170 | bail: | 172 | bail: |
171 | return status; | 173 | return status; |
@@ -173,18 +175,11 @@ bail: | |||
173 | 175 | ||
174 | void ocfs2_clear_hb_callbacks(struct ocfs2_super *osb) | 176 | void ocfs2_clear_hb_callbacks(struct ocfs2_super *osb) |
175 | { | 177 | { |
176 | int status; | ||
177 | |||
178 | if (ocfs2_mount_local(osb)) | 178 | if (ocfs2_mount_local(osb)) |
179 | return; | 179 | return; |
180 | 180 | ||
181 | status = o2hb_unregister_callback(&osb->osb_hb_down); | 181 | o2hb_unregister_callback(&osb->osb_hb_down); |
182 | if (status < 0) | 182 | o2hb_unregister_callback(&osb->osb_hb_up); |
183 | mlog_errno(status); | ||
184 | |||
185 | status = o2hb_unregister_callback(&osb->osb_hb_up); | ||
186 | if (status < 0) | ||
187 | mlog_errno(status); | ||
188 | } | 183 | } |
189 | 184 | ||
190 | void ocfs2_stop_heartbeat(struct ocfs2_super *osb) | 185 | void ocfs2_stop_heartbeat(struct ocfs2_super *osb) |
diff --git a/fs/partitions/Kconfig b/fs/partitions/Kconfig index 74552c60b6..6e8bb66fe6 100644 --- a/fs/partitions/Kconfig +++ b/fs/partitions/Kconfig | |||
@@ -235,5 +235,4 @@ config EFI_PARTITION | |||
235 | select CRC32 | 235 | select CRC32 |
236 | help | 236 | help |
237 | Say Y here if you would like to use hard disks under Linux which | 237 | Say Y here if you would like to use hard disks under Linux which |
238 | were partitioned using EFI GPT. Presently only useful on the | 238 | were partitioned using EFI GPT. |
239 | IA-64 platform. | ||
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index e46d237b10..8a7d0035ad 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -541,7 +541,7 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev) | |||
541 | if (!get_capacity(disk) || !(state = check_partition(disk, bdev))) | 541 | if (!get_capacity(disk) || !(state = check_partition(disk, bdev))) |
542 | return 0; | 542 | return 0; |
543 | if (IS_ERR(state)) /* I/O error reading the partition table */ | 543 | if (IS_ERR(state)) /* I/O error reading the partition table */ |
544 | return PTR_ERR(state); | 544 | return -EIO; |
545 | for (p = 1; p < state->limit; p++) { | 545 | for (p = 1; p < state->limit; p++) { |
546 | sector_t size = state->parts[p].size; | 546 | sector_t size = state->parts[p].size; |
547 | sector_t from = state->parts[p].from; | 547 | sector_t from = state->parts[p].from; |
diff --git a/fs/proc/Makefile b/fs/proc/Makefile index a6b3a8f878..bce38e3f06 100644 --- a/fs/proc/Makefile +++ b/fs/proc/Makefile | |||
@@ -8,8 +8,9 @@ proc-y := nommu.o task_nommu.o | |||
8 | proc-$(CONFIG_MMU) := mmu.o task_mmu.o | 8 | proc-$(CONFIG_MMU) := mmu.o task_mmu.o |
9 | 9 | ||
10 | proc-y += inode.o root.o base.o generic.o array.o \ | 10 | proc-y += inode.o root.o base.o generic.o array.o \ |
11 | proc_tty.o proc_misc.o proc_sysctl.o | 11 | proc_tty.o proc_misc.o |
12 | 12 | ||
13 | proc-$(CONFIG_PROC_SYSCTL) += proc_sysctl.o | ||
13 | proc-$(CONFIG_PROC_KCORE) += kcore.o | 14 | proc-$(CONFIG_PROC_KCORE) += kcore.o |
14 | proc-$(CONFIG_PROC_VMCORE) += vmcore.o | 15 | proc-$(CONFIG_PROC_VMCORE) += vmcore.o |
15 | proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o | 16 | proc-$(CONFIG_PROC_DEVICETREE) += proc_devtree.o |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 01f7769da8..989af5e55d 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -1558,29 +1558,20 @@ static ssize_t proc_pid_attr_read(struct file * file, char __user * buf, | |||
1558 | size_t count, loff_t *ppos) | 1558 | size_t count, loff_t *ppos) |
1559 | { | 1559 | { |
1560 | struct inode * inode = file->f_path.dentry->d_inode; | 1560 | struct inode * inode = file->f_path.dentry->d_inode; |
1561 | unsigned long page; | 1561 | char *p = NULL; |
1562 | ssize_t length; | 1562 | ssize_t length; |
1563 | struct task_struct *task = get_proc_task(inode); | 1563 | struct task_struct *task = get_proc_task(inode); |
1564 | 1564 | ||
1565 | length = -ESRCH; | ||
1566 | if (!task) | 1565 | if (!task) |
1567 | goto out_no_task; | 1566 | return -ESRCH; |
1568 | |||
1569 | if (count > PAGE_SIZE) | ||
1570 | count = PAGE_SIZE; | ||
1571 | length = -ENOMEM; | ||
1572 | if (!(page = __get_free_page(GFP_KERNEL))) | ||
1573 | goto out; | ||
1574 | 1567 | ||
1575 | length = security_getprocattr(task, | 1568 | length = security_getprocattr(task, |
1576 | (char*)file->f_path.dentry->d_name.name, | 1569 | (char*)file->f_path.dentry->d_name.name, |
1577 | (void*)page, count); | 1570 | &p); |
1578 | if (length >= 0) | ||
1579 | length = simple_read_from_buffer(buf, count, ppos, (char *)page, length); | ||
1580 | free_page(page); | ||
1581 | out: | ||
1582 | put_task_struct(task); | 1571 | put_task_struct(task); |
1583 | out_no_task: | 1572 | if (length > 0) |
1573 | length = simple_read_from_buffer(buf, count, ppos, p, length); | ||
1574 | kfree(p); | ||
1584 | return length; | 1575 | return length; |
1585 | } | 1576 | } |
1586 | 1577 | ||
diff --git a/fs/smbfs/request.c b/fs/smbfs/request.c index 42261dbdf6..723f7c6676 100644 --- a/fs/smbfs/request.c +++ b/fs/smbfs/request.c | |||
@@ -181,6 +181,7 @@ static int smb_setup_request(struct smb_request *req) | |||
181 | req->rq_errno = 0; | 181 | req->rq_errno = 0; |
182 | req->rq_fragment = 0; | 182 | req->rq_fragment = 0; |
183 | kfree(req->rq_trans2buffer); | 183 | kfree(req->rq_trans2buffer); |
184 | req->rq_trans2buffer = NULL; | ||
184 | 185 | ||
185 | return 0; | 186 | return 0; |
186 | } | 187 | } |
diff --git a/fs/splice.c b/fs/splice.c index 2fca6ebf4c..07f6556add 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -576,76 +576,21 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, | |||
576 | if (this_len + offset > PAGE_CACHE_SIZE) | 576 | if (this_len + offset > PAGE_CACHE_SIZE) |
577 | this_len = PAGE_CACHE_SIZE - offset; | 577 | this_len = PAGE_CACHE_SIZE - offset; |
578 | 578 | ||
579 | /* | ||
580 | * Reuse buf page, if SPLICE_F_MOVE is set and we are doing a full | ||
581 | * page. | ||
582 | */ | ||
583 | if ((sd->flags & SPLICE_F_MOVE) && this_len == PAGE_CACHE_SIZE) { | ||
584 | /* | ||
585 | * If steal succeeds, buf->page is now pruned from the | ||
586 | * pagecache and we can reuse it. The page will also be | ||
587 | * locked on successful return. | ||
588 | */ | ||
589 | if (buf->ops->steal(pipe, buf)) | ||
590 | goto find_page; | ||
591 | |||
592 | page = buf->page; | ||
593 | if (add_to_page_cache(page, mapping, index, GFP_KERNEL)) { | ||
594 | unlock_page(page); | ||
595 | goto find_page; | ||
596 | } | ||
597 | |||
598 | page_cache_get(page); | ||
599 | |||
600 | if (!(buf->flags & PIPE_BUF_FLAG_LRU)) | ||
601 | lru_cache_add(page); | ||
602 | } else { | ||
603 | find_page: | 579 | find_page: |
604 | page = find_lock_page(mapping, index); | 580 | page = find_lock_page(mapping, index); |
605 | if (!page) { | 581 | if (!page) { |
606 | ret = -ENOMEM; | 582 | ret = -ENOMEM; |
607 | page = page_cache_alloc_cold(mapping); | 583 | page = page_cache_alloc_cold(mapping); |
608 | if (unlikely(!page)) | 584 | if (unlikely(!page)) |
609 | goto out_ret; | 585 | goto out_ret; |
610 | |||
611 | /* | ||
612 | * This will also lock the page | ||
613 | */ | ||
614 | ret = add_to_page_cache_lru(page, mapping, index, | ||
615 | GFP_KERNEL); | ||
616 | if (unlikely(ret)) | ||
617 | goto out; | ||
618 | } | ||
619 | 586 | ||
620 | /* | 587 | /* |
621 | * We get here with the page locked. If the page is also | 588 | * This will also lock the page |
622 | * uptodate, we don't need to do more. If it isn't, we | ||
623 | * may need to bring it in if we are not going to overwrite | ||
624 | * the full page. | ||
625 | */ | 589 | */ |
626 | if (!PageUptodate(page)) { | 590 | ret = add_to_page_cache_lru(page, mapping, index, |
627 | if (this_len < PAGE_CACHE_SIZE) { | 591 | GFP_KERNEL); |
628 | ret = mapping->a_ops->readpage(file, page); | 592 | if (unlikely(ret)) |
629 | if (unlikely(ret)) | 593 | goto out; |
630 | goto out; | ||
631 | |||
632 | lock_page(page); | ||
633 | |||
634 | if (!PageUptodate(page)) { | ||
635 | /* | ||
636 | * Page got invalidated, repeat. | ||
637 | */ | ||
638 | if (!page->mapping) { | ||
639 | unlock_page(page); | ||
640 | page_cache_release(page); | ||
641 | goto find_page; | ||
642 | } | ||
643 | ret = -EIO; | ||
644 | goto out; | ||
645 | } | ||
646 | } else | ||
647 | SetPageUptodate(page); | ||
648 | } | ||
649 | } | 594 | } |
650 | 595 | ||
651 | ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len); | 596 | ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len); |
@@ -706,9 +651,9 @@ out_ret: | |||
706 | * key here is the 'actor' worker passed in that actually moves the data | 651 | * key here is the 'actor' worker passed in that actually moves the data |
707 | * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. | 652 | * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. |
708 | */ | 653 | */ |
709 | static ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, | 654 | ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, |
710 | struct file *out, loff_t *ppos, size_t len, | 655 | struct file *out, loff_t *ppos, size_t len, |
711 | unsigned int flags, splice_actor *actor) | 656 | unsigned int flags, splice_actor *actor) |
712 | { | 657 | { |
713 | int ret, do_wakeup, err; | 658 | int ret, do_wakeup, err; |
714 | struct splice_desc sd; | 659 | struct splice_desc sd; |
@@ -802,6 +747,7 @@ static ssize_t __splice_from_pipe(struct pipe_inode_info *pipe, | |||
802 | 747 | ||
803 | return ret; | 748 | return ret; |
804 | } | 749 | } |
750 | EXPORT_SYMBOL(__splice_from_pipe); | ||
805 | 751 | ||
806 | ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, | 752 | ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, |
807 | loff_t *ppos, size_t len, unsigned int flags, | 753 | loff_t *ppos, size_t len, unsigned int flags, |
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index 8d4d839a9d..fc4633378d 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -168,12 +168,12 @@ sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos) | |||
168 | ssize_t retval = 0; | 168 | ssize_t retval = 0; |
169 | 169 | ||
170 | down(&buffer->sem); | 170 | down(&buffer->sem); |
171 | if (buffer->orphaned) { | ||
172 | retval = -ENODEV; | ||
173 | goto out; | ||
174 | } | ||
175 | if (buffer->needs_read_fill) { | 171 | if (buffer->needs_read_fill) { |
176 | if ((retval = fill_read_buffer(file->f_path.dentry,buffer))) | 172 | if (buffer->orphaned) |
173 | retval = -ENODEV; | ||
174 | else | ||
175 | retval = fill_read_buffer(file->f_path.dentry,buffer); | ||
176 | if (retval) | ||
177 | goto out; | 177 | goto out; |
178 | } | 178 | } |
179 | pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n", | 179 | pr_debug("%s: count = %zd, ppos = %lld, buf = %s\n", |
@@ -629,6 +629,60 @@ void sysfs_remove_file_from_group(struct kobject *kobj, | |||
629 | } | 629 | } |
630 | EXPORT_SYMBOL_GPL(sysfs_remove_file_from_group); | 630 | EXPORT_SYMBOL_GPL(sysfs_remove_file_from_group); |
631 | 631 | ||
632 | struct sysfs_schedule_callback_struct { | ||
633 | struct kobject *kobj; | ||
634 | void (*func)(void *); | ||
635 | void *data; | ||
636 | struct work_struct work; | ||
637 | }; | ||
638 | |||
639 | static void sysfs_schedule_callback_work(struct work_struct *work) | ||
640 | { | ||
641 | struct sysfs_schedule_callback_struct *ss = container_of(work, | ||
642 | struct sysfs_schedule_callback_struct, work); | ||
643 | |||
644 | (ss->func)(ss->data); | ||
645 | kobject_put(ss->kobj); | ||
646 | kfree(ss); | ||
647 | } | ||
648 | |||
649 | /** | ||
650 | * sysfs_schedule_callback - helper to schedule a callback for a kobject | ||
651 | * @kobj: object we're acting for. | ||
652 | * @func: callback function to invoke later. | ||
653 | * @data: argument to pass to @func. | ||
654 | * | ||
655 | * sysfs attribute methods must not unregister themselves or their parent | ||
656 | * kobject (which would amount to the same thing). Attempts to do so will | ||
657 | * deadlock, since unregistration is mutually exclusive with driver | ||
658 | * callbacks. | ||
659 | * | ||
660 | * Instead methods can call this routine, which will attempt to allocate | ||
661 | * and schedule a workqueue request to call back @func with @data as its | ||
662 | * argument in the workqueue's process context. @kobj will be pinned | ||
663 | * until @func returns. | ||
664 | * | ||
665 | * Returns 0 if the request was submitted, -ENOMEM if storage could not | ||
666 | * be allocated. | ||
667 | */ | ||
668 | int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *), | ||
669 | void *data) | ||
670 | { | ||
671 | struct sysfs_schedule_callback_struct *ss; | ||
672 | |||
673 | ss = kmalloc(sizeof(*ss), GFP_KERNEL); | ||
674 | if (!ss) | ||
675 | return -ENOMEM; | ||
676 | kobject_get(kobj); | ||
677 | ss->kobj = kobj; | ||
678 | ss->func = func; | ||
679 | ss->data = data; | ||
680 | INIT_WORK(&ss->work, sysfs_schedule_callback_work); | ||
681 | schedule_work(&ss->work); | ||
682 | return 0; | ||
683 | } | ||
684 | EXPORT_SYMBOL_GPL(sysfs_schedule_callback); | ||
685 | |||
632 | 686 | ||
633 | EXPORT_SYMBOL_GPL(sysfs_create_file); | 687 | EXPORT_SYMBOL_GPL(sysfs_create_file); |
634 | EXPORT_SYMBOL_GPL(sysfs_remove_file); | 688 | EXPORT_SYMBOL_GPL(sysfs_remove_file); |
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c index ccb7d722c5..4de5c6b899 100644 --- a/fs/sysfs/inode.c +++ b/fs/sysfs/inode.c | |||
@@ -222,13 +222,17 @@ const unsigned char * sysfs_get_name(struct sysfs_dirent *sd) | |||
222 | 222 | ||
223 | static inline void orphan_all_buffers(struct inode *node) | 223 | static inline void orphan_all_buffers(struct inode *node) |
224 | { | 224 | { |
225 | struct sysfs_buffer_collection *set = node->i_private; | 225 | struct sysfs_buffer_collection *set; |
226 | struct sysfs_buffer *buf; | 226 | struct sysfs_buffer *buf; |
227 | 227 | ||
228 | mutex_lock_nested(&node->i_mutex, I_MUTEX_CHILD); | 228 | mutex_lock_nested(&node->i_mutex, I_MUTEX_CHILD); |
229 | if (node->i_private) { | 229 | set = node->i_private; |
230 | list_for_each_entry(buf, &set->associates, associates) | 230 | if (set) { |
231 | list_for_each_entry(buf, &set->associates, associates) { | ||
232 | down(&buf->sem); | ||
231 | buf->orphaned = 1; | 233 | buf->orphaned = 1; |
234 | up(&buf->sem); | ||
235 | } | ||
232 | } | 236 | } |
233 | mutex_unlock(&node->i_mutex); | 237 | mutex_unlock(&node->i_mutex); |
234 | } | 238 | } |
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c index bcc44084e0..841ac25fd9 100644 --- a/fs/ufs/balloc.c +++ b/fs/ufs/balloc.c | |||
@@ -244,62 +244,87 @@ failed: | |||
244 | * We can come here from ufs_writepage or ufs_prepare_write, | 244 | * We can come here from ufs_writepage or ufs_prepare_write, |
245 | * locked_page is argument of these functions, so we already lock it. | 245 | * locked_page is argument of these functions, so we already lock it. |
246 | */ | 246 | */ |
247 | static void ufs_change_blocknr(struct inode *inode, unsigned int beg, | 247 | static void ufs_change_blocknr(struct inode *inode, sector_t beg, |
248 | unsigned int count, unsigned int oldb, | 248 | unsigned int count, sector_t oldb, |
249 | unsigned int newb, struct page *locked_page) | 249 | sector_t newb, struct page *locked_page) |
250 | { | 250 | { |
251 | const unsigned mask = (1 << (PAGE_CACHE_SHIFT - inode->i_blkbits)) - 1; | 251 | const unsigned blks_per_page = |
252 | 1 << (PAGE_CACHE_SHIFT - inode->i_blkbits); | ||
253 | const unsigned mask = blks_per_page - 1; | ||
252 | struct address_space * const mapping = inode->i_mapping; | 254 | struct address_space * const mapping = inode->i_mapping; |
253 | pgoff_t index, cur_index; | 255 | pgoff_t index, cur_index, last_index; |
254 | unsigned end, pos, j; | 256 | unsigned pos, j, lblock; |
257 | sector_t end, i; | ||
255 | struct page *page; | 258 | struct page *page; |
256 | struct buffer_head *head, *bh; | 259 | struct buffer_head *head, *bh; |
257 | 260 | ||
258 | UFSD("ENTER, ino %lu, count %u, oldb %u, newb %u\n", | 261 | UFSD("ENTER, ino %lu, count %u, oldb %llu, newb %llu\n", |
259 | inode->i_ino, count, oldb, newb); | 262 | inode->i_ino, count, |
263 | (unsigned long long)oldb, (unsigned long long)newb); | ||
260 | 264 | ||
261 | BUG_ON(!locked_page); | 265 | BUG_ON(!locked_page); |
262 | BUG_ON(!PageLocked(locked_page)); | 266 | BUG_ON(!PageLocked(locked_page)); |
263 | 267 | ||
264 | cur_index = locked_page->index; | 268 | cur_index = locked_page->index; |
265 | 269 | end = count + beg; | |
266 | for (end = count + beg; beg < end; beg = (beg | mask) + 1) { | 270 | last_index = end >> (PAGE_CACHE_SHIFT - inode->i_blkbits); |
267 | index = beg >> (PAGE_CACHE_SHIFT - inode->i_blkbits); | 271 | for (i = beg; i < end; i = (i | mask) + 1) { |
272 | index = i >> (PAGE_CACHE_SHIFT - inode->i_blkbits); | ||
268 | 273 | ||
269 | if (likely(cur_index != index)) { | 274 | if (likely(cur_index != index)) { |
270 | page = ufs_get_locked_page(mapping, index); | 275 | page = ufs_get_locked_page(mapping, index); |
271 | if (!page || IS_ERR(page)) /* it was truncated or EIO */ | 276 | if (!page)/* it was truncated */ |
277 | continue; | ||
278 | if (IS_ERR(page)) {/* or EIO */ | ||
279 | ufs_error(inode->i_sb, __FUNCTION__, | ||
280 | "read of page %llu failed\n", | ||
281 | (unsigned long long)index); | ||
272 | continue; | 282 | continue; |
283 | } | ||
273 | } else | 284 | } else |
274 | page = locked_page; | 285 | page = locked_page; |
275 | 286 | ||
276 | head = page_buffers(page); | 287 | head = page_buffers(page); |
277 | bh = head; | 288 | bh = head; |
278 | pos = beg & mask; | 289 | pos = i & mask; |
279 | for (j = 0; j < pos; ++j) | 290 | for (j = 0; j < pos; ++j) |
280 | bh = bh->b_this_page; | 291 | bh = bh->b_this_page; |
281 | j = 0; | 292 | |
293 | |||
294 | if (unlikely(index == last_index)) | ||
295 | lblock = end & mask; | ||
296 | else | ||
297 | lblock = blks_per_page; | ||
298 | |||
282 | do { | 299 | do { |
283 | if (buffer_mapped(bh)) { | 300 | if (j >= lblock) |
284 | pos = bh->b_blocknr - oldb; | 301 | break; |
285 | if (pos < count) { | 302 | pos = (i - beg) + j; |
286 | UFSD(" change from %llu to %llu\n", | 303 | |
287 | (unsigned long long)pos + oldb, | 304 | if (!buffer_mapped(bh)) |
288 | (unsigned long long)pos + newb); | 305 | map_bh(bh, inode->i_sb, oldb + pos); |
289 | bh->b_blocknr = newb + pos; | 306 | if (!buffer_uptodate(bh)) { |
290 | unmap_underlying_metadata(bh->b_bdev, | 307 | ll_rw_block(READ, 1, &bh); |
291 | bh->b_blocknr); | 308 | wait_on_buffer(bh); |
292 | mark_buffer_dirty(bh); | 309 | if (!buffer_uptodate(bh)) { |
293 | ++j; | 310 | ufs_error(inode->i_sb, __FUNCTION__, |
311 | "read of block failed\n"); | ||
312 | break; | ||
294 | } | 313 | } |
295 | } | 314 | } |
296 | 315 | ||
316 | UFSD(" change from %llu to %llu, pos %u\n", | ||
317 | (unsigned long long)pos + oldb, | ||
318 | (unsigned long long)pos + newb, pos); | ||
319 | |||
320 | bh->b_blocknr = newb + pos; | ||
321 | unmap_underlying_metadata(bh->b_bdev, | ||
322 | bh->b_blocknr); | ||
323 | mark_buffer_dirty(bh); | ||
324 | ++j; | ||
297 | bh = bh->b_this_page; | 325 | bh = bh->b_this_page; |
298 | } while (bh != head); | 326 | } while (bh != head); |
299 | 327 | ||
300 | if (j) | ||
301 | set_page_dirty(page); | ||
302 | |||
303 | if (likely(cur_index != index)) | 328 | if (likely(cur_index != index)) |
304 | ufs_put_locked_page(page); | 329 | ufs_put_locked_page(page); |
305 | } | 330 | } |
@@ -457,8 +482,9 @@ u64 ufs_new_fragments(struct inode *inode, void *p, u64 fragment, | |||
457 | if (result) { | 482 | if (result) { |
458 | ufs_clear_frags(inode, result + oldcount, newcount - oldcount, | 483 | ufs_clear_frags(inode, result + oldcount, newcount - oldcount, |
459 | locked_page != NULL); | 484 | locked_page != NULL); |
460 | ufs_change_blocknr(inode, fragment - oldcount, oldcount, tmp, | 485 | ufs_change_blocknr(inode, fragment - oldcount, oldcount, |
461 | result, locked_page); | 486 | uspi->s_sbbase + tmp, |
487 | uspi->s_sbbase + result, locked_page); | ||
462 | ufs_cpu_to_data_ptr(sb, p, result); | 488 | ufs_cpu_to_data_ptr(sb, p, result); |
463 | *err = 0; | 489 | *err = 0; |
464 | UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); | 490 | UFS_I(inode)->i_lastfrag = max_t(u32, UFS_I(inode)->i_lastfrag, fragment + count); |
diff --git a/fs/ufs/ialloc.c b/fs/ufs/ialloc.c index b868878009..c28a8b6f2f 100644 --- a/fs/ufs/ialloc.c +++ b/fs/ufs/ialloc.c | |||
@@ -343,9 +343,8 @@ cg_found: | |||
343 | lock_buffer(bh); | 343 | lock_buffer(bh); |
344 | ufs2_inode = (struct ufs2_inode *)bh->b_data; | 344 | ufs2_inode = (struct ufs2_inode *)bh->b_data; |
345 | ufs2_inode += ufs_inotofsbo(inode->i_ino); | 345 | ufs2_inode += ufs_inotofsbo(inode->i_ino); |
346 | ufs2_inode->ui_birthtime.tv_sec = | 346 | ufs2_inode->ui_birthtime = cpu_to_fs64(sb, CURRENT_TIME.tv_sec); |
347 | cpu_to_fs32(sb, CURRENT_TIME_SEC.tv_sec); | 347 | ufs2_inode->ui_birthnsec = cpu_to_fs32(sb, CURRENT_TIME.tv_nsec); |
348 | ufs2_inode->ui_birthtime.tv_usec = 0; | ||
349 | mark_buffer_dirty(bh); | 348 | mark_buffer_dirty(bh); |
350 | unlock_buffer(bh); | 349 | unlock_buffer(bh); |
351 | if (sb->s_flags & MS_SYNCHRONOUS) | 350 | if (sb->s_flags & MS_SYNCHRONOUS) |
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index fb34ad03e2..013d7afe7c 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c | |||
@@ -212,7 +212,7 @@ repeat: | |||
212 | brelse (result); | 212 | brelse (result); |
213 | goto repeat; | 213 | goto repeat; |
214 | } else { | 214 | } else { |
215 | *phys = tmp + blockoff; | 215 | *phys = uspi->s_sbbase + tmp + blockoff; |
216 | return NULL; | 216 | return NULL; |
217 | } | 217 | } |
218 | } | 218 | } |
@@ -282,9 +282,9 @@ repeat: | |||
282 | } | 282 | } |
283 | 283 | ||
284 | if (!phys) { | 284 | if (!phys) { |
285 | result = sb_getblk(sb, tmp + blockoff); | 285 | result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff); |
286 | } else { | 286 | } else { |
287 | *phys = tmp + blockoff; | 287 | *phys = uspi->s_sbbase + tmp + blockoff; |
288 | result = NULL; | 288 | result = NULL; |
289 | *err = 0; | 289 | *err = 0; |
290 | *new = 1; | 290 | *new = 1; |
@@ -368,7 +368,7 @@ repeat: | |||
368 | brelse (result); | 368 | brelse (result); |
369 | goto repeat; | 369 | goto repeat; |
370 | } else { | 370 | } else { |
371 | *phys = tmp + blockoff; | 371 | *phys = uspi->s_sbbase + tmp + blockoff; |
372 | goto out; | 372 | goto out; |
373 | } | 373 | } |
374 | } | 374 | } |
@@ -389,9 +389,9 @@ repeat: | |||
389 | 389 | ||
390 | 390 | ||
391 | if (!phys) { | 391 | if (!phys) { |
392 | result = sb_getblk(sb, tmp + blockoff); | 392 | result = sb_getblk(sb, uspi->s_sbbase + tmp + blockoff); |
393 | } else { | 393 | } else { |
394 | *phys = tmp + blockoff; | 394 | *phys = uspi->s_sbbase + tmp + blockoff; |
395 | *new = 1; | 395 | *new = 1; |
396 | } | 396 | } |
397 | 397 | ||
@@ -668,12 +668,12 @@ static void ufs2_read_inode(struct inode *inode, struct ufs2_inode *ufs2_inode) | |||
668 | inode->i_gid = fs32_to_cpu(sb, ufs2_inode->ui_gid); | 668 | inode->i_gid = fs32_to_cpu(sb, ufs2_inode->ui_gid); |
669 | 669 | ||
670 | inode->i_size = fs64_to_cpu(sb, ufs2_inode->ui_size); | 670 | inode->i_size = fs64_to_cpu(sb, ufs2_inode->ui_size); |
671 | inode->i_atime.tv_sec = fs32_to_cpu(sb, ufs2_inode->ui_atime.tv_sec); | 671 | inode->i_atime.tv_sec = fs64_to_cpu(sb, ufs2_inode->ui_atime); |
672 | inode->i_ctime.tv_sec = fs32_to_cpu(sb, ufs2_inode->ui_ctime.tv_sec); | 672 | inode->i_ctime.tv_sec = fs64_to_cpu(sb, ufs2_inode->ui_ctime); |
673 | inode->i_mtime.tv_sec = fs32_to_cpu(sb, ufs2_inode->ui_mtime.tv_sec); | 673 | inode->i_mtime.tv_sec = fs64_to_cpu(sb, ufs2_inode->ui_mtime); |
674 | inode->i_mtime.tv_nsec = 0; | 674 | inode->i_atime.tv_nsec = fs32_to_cpu(sb, ufs2_inode->ui_atimensec); |
675 | inode->i_atime.tv_nsec = 0; | 675 | inode->i_ctime.tv_nsec = fs32_to_cpu(sb, ufs2_inode->ui_ctimensec); |
676 | inode->i_ctime.tv_nsec = 0; | 676 | inode->i_mtime.tv_nsec = fs32_to_cpu(sb, ufs2_inode->ui_mtimensec); |
677 | inode->i_blocks = fs64_to_cpu(sb, ufs2_inode->ui_blocks); | 677 | inode->i_blocks = fs64_to_cpu(sb, ufs2_inode->ui_blocks); |
678 | inode->i_generation = fs32_to_cpu(sb, ufs2_inode->ui_gen); | 678 | inode->i_generation = fs32_to_cpu(sb, ufs2_inode->ui_gen); |
679 | ufsi->i_flags = fs32_to_cpu(sb, ufs2_inode->ui_flags); | 679 | ufsi->i_flags = fs32_to_cpu(sb, ufs2_inode->ui_flags); |
@@ -803,12 +803,12 @@ static void ufs2_update_inode(struct inode *inode, struct ufs2_inode *ufs_inode) | |||
803 | ufs_inode->ui_gid = cpu_to_fs32(sb, inode->i_gid); | 803 | ufs_inode->ui_gid = cpu_to_fs32(sb, inode->i_gid); |
804 | 804 | ||
805 | ufs_inode->ui_size = cpu_to_fs64(sb, inode->i_size); | 805 | ufs_inode->ui_size = cpu_to_fs64(sb, inode->i_size); |
806 | ufs_inode->ui_atime.tv_sec = cpu_to_fs32(sb, inode->i_atime.tv_sec); | 806 | ufs_inode->ui_atime = cpu_to_fs64(sb, inode->i_atime.tv_sec); |
807 | ufs_inode->ui_atime.tv_usec = 0; | 807 | ufs_inode->ui_atimensec = cpu_to_fs32(sb, inode->i_atime.tv_nsec); |
808 | ufs_inode->ui_ctime.tv_sec = cpu_to_fs32(sb, inode->i_ctime.tv_sec); | 808 | ufs_inode->ui_ctime = cpu_to_fs64(sb, inode->i_ctime.tv_sec); |
809 | ufs_inode->ui_ctime.tv_usec = 0; | 809 | ufs_inode->ui_ctimensec = cpu_to_fs32(sb, inode->i_ctime.tv_nsec); |
810 | ufs_inode->ui_mtime.tv_sec = cpu_to_fs32(sb, inode->i_mtime.tv_sec); | 810 | ufs_inode->ui_mtime = cpu_to_fs64(sb, inode->i_mtime.tv_sec); |
811 | ufs_inode->ui_mtime.tv_usec = 0; | 811 | ufs_inode->ui_mtimensec = cpu_to_fs32(sb, inode->i_mtime.tv_nsec); |
812 | 812 | ||
813 | ufs_inode->ui_blocks = cpu_to_fs64(sb, inode->i_blocks); | 813 | ufs_inode->ui_blocks = cpu_to_fs64(sb, inode->i_blocks); |
814 | ufs_inode->ui_flags = cpu_to_fs32(sb, ufsi->i_flags); | 814 | ufs_inode->ui_flags = cpu_to_fs32(sb, ufsi->i_flags); |
diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c index 749581fa77..79c54c85fb 100644 --- a/fs/ufs/truncate.c +++ b/fs/ufs/truncate.c | |||
@@ -74,7 +74,7 @@ static int ufs_trunc_direct(struct inode *inode) | |||
74 | unsigned i, tmp; | 74 | unsigned i, tmp; |
75 | int retry; | 75 | int retry; |
76 | 76 | ||
77 | UFSD("ENTER\n"); | 77 | UFSD("ENTER: ino %lu\n", inode->i_ino); |
78 | 78 | ||
79 | sb = inode->i_sb; | 79 | sb = inode->i_sb; |
80 | uspi = UFS_SB(sb)->s_uspi; | 80 | uspi = UFS_SB(sb)->s_uspi; |
@@ -96,8 +96,8 @@ static int ufs_trunc_direct(struct inode *inode) | |||
96 | block2 = ufs_fragstoblks (frag3); | 96 | block2 = ufs_fragstoblks (frag3); |
97 | } | 97 | } |
98 | 98 | ||
99 | UFSD("frag1 %llu, frag2 %llu, block1 %llu, block2 %llu, frag3 %llu," | 99 | UFSD("ino %lu, frag1 %llu, frag2 %llu, block1 %llu, block2 %llu," |
100 | " frag4 %llu\n", | 100 | " frag3 %llu, frag4 %llu\n", inode->i_ino, |
101 | (unsigned long long)frag1, (unsigned long long)frag2, | 101 | (unsigned long long)frag1, (unsigned long long)frag2, |
102 | (unsigned long long)block1, (unsigned long long)block2, | 102 | (unsigned long long)block1, (unsigned long long)block2, |
103 | (unsigned long long)frag3, (unsigned long long)frag4); | 103 | (unsigned long long)frag3, (unsigned long long)frag4); |
@@ -163,7 +163,7 @@ next1: | |||
163 | mark_inode_dirty(inode); | 163 | mark_inode_dirty(inode); |
164 | next3: | 164 | next3: |
165 | 165 | ||
166 | UFSD("EXIT\n"); | 166 | UFSD("EXIT: ino %lu\n", inode->i_ino); |
167 | return retry; | 167 | return retry; |
168 | } | 168 | } |
169 | 169 | ||
@@ -248,7 +248,7 @@ static int ufs_trunc_indirect(struct inode *inode, u64 offset, void *p) | |||
248 | } | 248 | } |
249 | ubh_brelse (ind_ubh); | 249 | ubh_brelse (ind_ubh); |
250 | 250 | ||
251 | UFSD("EXIT\n"); | 251 | UFSD("EXIT: ino %lu\n", inode->i_ino); |
252 | 252 | ||
253 | return retry; | 253 | return retry; |
254 | } | 254 | } |
@@ -262,7 +262,7 @@ static int ufs_trunc_dindirect(struct inode *inode, u64 offset, void *p) | |||
262 | void *dind; | 262 | void *dind; |
263 | int retry = 0; | 263 | int retry = 0; |
264 | 264 | ||
265 | UFSD("ENTER\n"); | 265 | UFSD("ENTER: ino %lu\n", inode->i_ino); |
266 | 266 | ||
267 | sb = inode->i_sb; | 267 | sb = inode->i_sb; |
268 | uspi = UFS_SB(sb)->s_uspi; | 268 | uspi = UFS_SB(sb)->s_uspi; |
@@ -312,7 +312,7 @@ static int ufs_trunc_dindirect(struct inode *inode, u64 offset, void *p) | |||
312 | } | 312 | } |
313 | ubh_brelse (dind_bh); | 313 | ubh_brelse (dind_bh); |
314 | 314 | ||
315 | UFSD("EXIT\n"); | 315 | UFSD("EXIT: ino %lu\n", inode->i_ino); |
316 | 316 | ||
317 | return retry; | 317 | return retry; |
318 | } | 318 | } |
@@ -327,7 +327,7 @@ static int ufs_trunc_tindirect(struct inode *inode) | |||
327 | void *tind, *p; | 327 | void *tind, *p; |
328 | int retry; | 328 | int retry; |
329 | 329 | ||
330 | UFSD("ENTER\n"); | 330 | UFSD("ENTER: ino %lu\n", inode->i_ino); |
331 | 331 | ||
332 | retry = 0; | 332 | retry = 0; |
333 | 333 | ||
@@ -348,7 +348,7 @@ static int ufs_trunc_tindirect(struct inode *inode) | |||
348 | } | 348 | } |
349 | 349 | ||
350 | for (i = tindirect_block ; i < uspi->s_apb ; i++) { | 350 | for (i = tindirect_block ; i < uspi->s_apb ; i++) { |
351 | tind = ubh_get_addr32 (tind_bh, i); | 351 | tind = ubh_get_data_ptr(uspi, tind_bh, i); |
352 | retry |= ufs_trunc_dindirect(inode, UFS_NDADDR + | 352 | retry |= ufs_trunc_dindirect(inode, UFS_NDADDR + |
353 | uspi->s_apb + ((i + 1) << uspi->s_2apbshift), tind); | 353 | uspi->s_apb + ((i + 1) << uspi->s_2apbshift), tind); |
354 | ubh_mark_buffer_dirty(tind_bh); | 354 | ubh_mark_buffer_dirty(tind_bh); |
@@ -372,19 +372,21 @@ static int ufs_trunc_tindirect(struct inode *inode) | |||
372 | } | 372 | } |
373 | ubh_brelse (tind_bh); | 373 | ubh_brelse (tind_bh); |
374 | 374 | ||
375 | UFSD("EXIT\n"); | 375 | UFSD("EXIT: ino %lu\n", inode->i_ino); |
376 | return retry; | 376 | return retry; |
377 | } | 377 | } |
378 | 378 | ||
379 | static int ufs_alloc_lastblock(struct inode *inode) | 379 | static int ufs_alloc_lastblock(struct inode *inode) |
380 | { | 380 | { |
381 | int err = 0; | 381 | int err = 0; |
382 | struct super_block *sb = inode->i_sb; | ||
382 | struct address_space *mapping = inode->i_mapping; | 383 | struct address_space *mapping = inode->i_mapping; |
383 | struct ufs_sb_private_info *uspi = UFS_SB(inode->i_sb)->s_uspi; | 384 | struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi; |
384 | unsigned i, end; | 385 | unsigned i, end; |
385 | sector_t lastfrag; | 386 | sector_t lastfrag; |
386 | struct page *lastpage; | 387 | struct page *lastpage; |
387 | struct buffer_head *bh; | 388 | struct buffer_head *bh; |
389 | u64 phys64; | ||
388 | 390 | ||
389 | lastfrag = (i_size_read(inode) + uspi->s_fsize - 1) >> uspi->s_fshift; | 391 | lastfrag = (i_size_read(inode) + uspi->s_fsize - 1) >> uspi->s_fshift; |
390 | 392 | ||
@@ -424,6 +426,20 @@ static int ufs_alloc_lastblock(struct inode *inode) | |||
424 | set_page_dirty(lastpage); | 426 | set_page_dirty(lastpage); |
425 | } | 427 | } |
426 | 428 | ||
429 | if (lastfrag >= UFS_IND_FRAGMENT) { | ||
430 | end = uspi->s_fpb - ufs_fragnum(lastfrag) - 1; | ||
431 | phys64 = bh->b_blocknr + 1; | ||
432 | for (i = 0; i < end; ++i) { | ||
433 | bh = sb_getblk(sb, i + phys64); | ||
434 | lock_buffer(bh); | ||
435 | memset(bh->b_data, 0, sb->s_blocksize); | ||
436 | set_buffer_uptodate(bh); | ||
437 | mark_buffer_dirty(bh); | ||
438 | unlock_buffer(bh); | ||
439 | sync_dirty_buffer(bh); | ||
440 | brelse(bh); | ||
441 | } | ||
442 | } | ||
427 | out_unlock: | 443 | out_unlock: |
428 | ufs_put_locked_page(lastpage); | 444 | ufs_put_locked_page(lastpage); |
429 | out: | 445 | out: |
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index e2bea6a661..69e9e80735 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c | |||
@@ -1829,11 +1829,11 @@ xfs_buf_init(void) | |||
1829 | if (!xfs_buf_zone) | 1829 | if (!xfs_buf_zone) |
1830 | goto out_free_trace_buf; | 1830 | goto out_free_trace_buf; |
1831 | 1831 | ||
1832 | xfslogd_workqueue = create_freezeable_workqueue("xfslogd"); | 1832 | xfslogd_workqueue = create_workqueue("xfslogd"); |
1833 | if (!xfslogd_workqueue) | 1833 | if (!xfslogd_workqueue) |
1834 | goto out_free_buf_zone; | 1834 | goto out_free_buf_zone; |
1835 | 1835 | ||
1836 | xfsdatad_workqueue = create_freezeable_workqueue("xfsdatad"); | 1836 | xfsdatad_workqueue = create_workqueue("xfsdatad"); |
1837 | if (!xfsdatad_workqueue) | 1837 | if (!xfsdatad_workqueue) |
1838 | goto out_destroy_xfslogd_workqueue; | 1838 | goto out_destroy_xfslogd_workqueue; |
1839 | 1839 | ||