diff options
author | Arnd Bergmann <arnd@arndb.de> | 2011-07-21 10:31:22 -0400 |
---|---|---|
committer | Arnd Bergmann <arnd@arndb.de> | 2011-07-21 10:31:22 -0400 |
commit | ab2a0e0d135490729e384c1826d118f92e88cae8 (patch) | |
tree | 58ab1e9e5d549feac9bf3beacbb6942f50d0bed9 /fs | |
parent | 09dd9b39abf85b8fae3ea105a81825478dd227b6 (diff) | |
parent | 2f3ab04a47c9b5e7c93400601e8f69bef0fa184a (diff) |
Merge branch 'next-samsung-cleanup' of git://git.kernel.org/pub/scm/linux/kernel/git/kgene/linux-samsung into next/cleanup
Diffstat (limited to 'fs')
-rw-r--r-- | fs/binfmt_elf_fdpic.c | 1 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 5 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 12 | ||||
-rw-r--r-- | fs/btrfs/super.c | 6 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 3 | ||||
-rw-r--r-- | fs/ceph/file.c | 14 | ||||
-rw-r--r-- | fs/cifs/cifsfs.c | 8 | ||||
-rw-r--r-- | fs/cifs/cifsproto.h | 6 | ||||
-rw-r--r-- | fs/cifs/connect.c | 116 | ||||
-rw-r--r-- | fs/cifs/fscache.c | 1 | ||||
-rw-r--r-- | fs/fscache/page.c | 44 | ||||
-rw-r--r-- | fs/hfsplus/super.c | 2 | ||||
-rw-r--r-- | fs/hfsplus/wrapper.c | 7 | ||||
-rw-r--r-- | fs/locks.c | 30 | ||||
-rw-r--r-- | fs/nfs/fscache.c | 8 | ||||
-rw-r--r-- | fs/xfs/xfs_inode_item.c | 14 | ||||
-rw-r--r-- | fs/xfs/xfs_trans.c | 4 |
17 files changed, 184 insertions, 97 deletions
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 63039ed9576f..2bc5dc644b4c 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
@@ -1864,6 +1864,7 @@ cleanup: | |||
1864 | kfree(psinfo); | 1864 | kfree(psinfo); |
1865 | kfree(notes); | 1865 | kfree(notes); |
1866 | kfree(fpu); | 1866 | kfree(fpu); |
1867 | kfree(shdr4extnum); | ||
1867 | #ifdef ELF_CORE_COPY_XFPREGS | 1868 | #ifdef ELF_CORE_COPY_XFPREGS |
1868 | kfree(xfpu); | 1869 | kfree(xfpu); |
1869 | #endif | 1870 | #endif |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index f30ac05dbda7..3b859a3e6a0e 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -1335,6 +1335,11 @@ struct btrfs_ioctl_defrag_range_args { | |||
1335 | */ | 1335 | */ |
1336 | #define BTRFS_STRING_ITEM_KEY 253 | 1336 | #define BTRFS_STRING_ITEM_KEY 253 |
1337 | 1337 | ||
1338 | /* | ||
1339 | * Flags for mount options. | ||
1340 | * | ||
1341 | * Note: don't forget to add new options to btrfs_show_options() | ||
1342 | */ | ||
1338 | #define BTRFS_MOUNT_NODATASUM (1 << 0) | 1343 | #define BTRFS_MOUNT_NODATASUM (1 << 0) |
1339 | #define BTRFS_MOUNT_NODATACOW (1 << 1) | 1344 | #define BTRFS_MOUNT_NODATACOW (1 << 1) |
1340 | #define BTRFS_MOUNT_NOBARRIER (1 << 2) | 1345 | #define BTRFS_MOUNT_NOBARRIER (1 << 2) |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index d340f63d8f07..3601f0aebddf 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -2678,12 +2678,14 @@ noinline int btrfs_update_inode(struct btrfs_trans_handle *trans, | |||
2678 | int ret; | 2678 | int ret; |
2679 | 2679 | ||
2680 | /* | 2680 | /* |
2681 | * If root is tree root, it means this inode is used to | 2681 | * If the inode is a free space inode, we can deadlock during commit |
2682 | * store free space information. And these inodes are updated | 2682 | * if we put it into the delayed code. |
2683 | * when committing the transaction, so they needn't delaye to | 2683 | * |
2684 | * be updated, or deadlock will occured. | 2684 | * The data relocation inode should also be directly updated |
2685 | * without delay | ||
2685 | */ | 2686 | */ |
2686 | if (!is_free_space_inode(root, inode)) { | 2687 | if (!is_free_space_inode(root, inode) |
2688 | && root->root_key.objectid != BTRFS_DATA_RELOC_TREE_OBJECTID) { | ||
2687 | ret = btrfs_delayed_update_inode(trans, root, inode); | 2689 | ret = btrfs_delayed_update_inode(trans, root, inode); |
2688 | if (!ret) | 2690 | if (!ret) |
2689 | btrfs_set_inode_last_trans(trans, inode); | 2691 | btrfs_set_inode_last_trans(trans, inode); |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 0bb4ebbb71b7..15634d4648d7 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -723,6 +723,12 @@ static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
723 | seq_puts(seq, ",clear_cache"); | 723 | seq_puts(seq, ",clear_cache"); |
724 | if (btrfs_test_opt(root, USER_SUBVOL_RM_ALLOWED)) | 724 | if (btrfs_test_opt(root, USER_SUBVOL_RM_ALLOWED)) |
725 | seq_puts(seq, ",user_subvol_rm_allowed"); | 725 | seq_puts(seq, ",user_subvol_rm_allowed"); |
726 | if (btrfs_test_opt(root, ENOSPC_DEBUG)) | ||
727 | seq_puts(seq, ",enospc_debug"); | ||
728 | if (btrfs_test_opt(root, AUTO_DEFRAG)) | ||
729 | seq_puts(seq, ",autodefrag"); | ||
730 | if (btrfs_test_opt(root, INODE_MAP_CACHE)) | ||
731 | seq_puts(seq, ",inode_cache"); | ||
726 | return 0; | 732 | return 0; |
727 | } | 733 | } |
728 | 734 | ||
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 1efa56e18f9b..19450bc53632 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -2098,7 +2098,8 @@ int btrfs_balance(struct btrfs_root *dev_root) | |||
2098 | chunk_root->root_key.objectid, | 2098 | chunk_root->root_key.objectid, |
2099 | found_key.objectid, | 2099 | found_key.objectid, |
2100 | found_key.offset); | 2100 | found_key.offset); |
2101 | BUG_ON(ret && ret != -ENOSPC); | 2101 | if (ret && ret != -ENOSPC) |
2102 | goto error; | ||
2102 | key.offset = found_key.offset - 1; | 2103 | key.offset = found_key.offset - 1; |
2103 | } | 2104 | } |
2104 | ret = 0; | 2105 | ret = 0; |
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 9542f07d0b93..4698a5c553dc 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -290,7 +290,6 @@ static int striped_read(struct inode *inode, | |||
290 | struct ceph_inode_info *ci = ceph_inode(inode); | 290 | struct ceph_inode_info *ci = ceph_inode(inode); |
291 | u64 pos, this_len; | 291 | u64 pos, this_len; |
292 | int io_align, page_align; | 292 | int io_align, page_align; |
293 | int page_off = off & ~PAGE_CACHE_MASK; /* first byte's offset in page */ | ||
294 | int left, pages_left; | 293 | int left, pages_left; |
295 | int read; | 294 | int read; |
296 | struct page **page_pos; | 295 | struct page **page_pos; |
@@ -326,12 +325,11 @@ more: | |||
326 | ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : ""); | 325 | ret, hit_stripe ? " HITSTRIPE" : "", was_short ? " SHORT" : ""); |
327 | 326 | ||
328 | if (ret > 0) { | 327 | if (ret > 0) { |
329 | int didpages = | 328 | int didpages = (page_align + ret) >> PAGE_CACHE_SHIFT; |
330 | ((pos & ~PAGE_CACHE_MASK) + ret) >> PAGE_CACHE_SHIFT; | ||
331 | 329 | ||
332 | if (read < pos - off) { | 330 | if (read < pos - off) { |
333 | dout(" zero gap %llu to %llu\n", off + read, pos); | 331 | dout(" zero gap %llu to %llu\n", off + read, pos); |
334 | ceph_zero_page_vector_range(page_off + read, | 332 | ceph_zero_page_vector_range(page_align + read, |
335 | pos - off - read, pages); | 333 | pos - off - read, pages); |
336 | } | 334 | } |
337 | pos += ret; | 335 | pos += ret; |
@@ -356,7 +354,7 @@ more: | |||
356 | left = inode->i_size - pos; | 354 | left = inode->i_size - pos; |
357 | 355 | ||
358 | dout("zero tail %d\n", left); | 356 | dout("zero tail %d\n", left); |
359 | ceph_zero_page_vector_range(page_off + read, left, | 357 | ceph_zero_page_vector_range(page_align + read, left, |
360 | pages); | 358 | pages); |
361 | read += left; | 359 | read += left; |
362 | } | 360 | } |
@@ -478,9 +476,6 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data, | |||
478 | else | 476 | else |
479 | pos = *offset; | 477 | pos = *offset; |
480 | 478 | ||
481 | io_align = pos & ~PAGE_MASK; | ||
482 | buf_align = (unsigned long)data & ~PAGE_MASK; | ||
483 | |||
484 | ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + left); | 479 | ret = filemap_write_and_wait_range(inode->i_mapping, pos, pos + left); |
485 | if (ret < 0) | 480 | if (ret < 0) |
486 | return ret; | 481 | return ret; |
@@ -504,6 +499,8 @@ static ssize_t ceph_sync_write(struct file *file, const char __user *data, | |||
504 | * boundary. this isn't atomic, unfortunately. :( | 499 | * boundary. this isn't atomic, unfortunately. :( |
505 | */ | 500 | */ |
506 | more: | 501 | more: |
502 | io_align = pos & ~PAGE_MASK; | ||
503 | buf_align = (unsigned long)data & ~PAGE_MASK; | ||
507 | len = left; | 504 | len = left; |
508 | if (file->f_flags & O_DIRECT) { | 505 | if (file->f_flags & O_DIRECT) { |
509 | /* write from beginning of first page, regardless of | 506 | /* write from beginning of first page, regardless of |
@@ -593,6 +590,7 @@ out: | |||
593 | pos += len; | 590 | pos += len; |
594 | written += len; | 591 | written += len; |
595 | left -= len; | 592 | left -= len; |
593 | data += written; | ||
596 | if (left) | 594 | if (left) |
597 | goto more; | 595 | goto more; |
598 | 596 | ||
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 35f9154615fa..3e2989976297 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -649,9 +649,9 @@ cifs_do_mount(struct file_system_type *fs_type, | |||
649 | 649 | ||
650 | cFYI(1, "Devname: %s flags: %d ", dev_name, flags); | 650 | cFYI(1, "Devname: %s flags: %d ", dev_name, flags); |
651 | 651 | ||
652 | rc = cifs_setup_volume_info(&volume_info, (char *)data, dev_name); | 652 | volume_info = cifs_get_volume_info((char *)data, dev_name); |
653 | if (rc) | 653 | if (IS_ERR(volume_info)) |
654 | return ERR_PTR(rc); | 654 | return ERR_CAST(volume_info); |
655 | 655 | ||
656 | cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL); | 656 | cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL); |
657 | if (cifs_sb == NULL) { | 657 | if (cifs_sb == NULL) { |
@@ -713,7 +713,7 @@ cifs_do_mount(struct file_system_type *fs_type, | |||
713 | out_super: | 713 | out_super: |
714 | deactivate_locked_super(sb); | 714 | deactivate_locked_super(sb); |
715 | out: | 715 | out: |
716 | cifs_cleanup_volume_info(&volume_info); | 716 | cifs_cleanup_volume_info(volume_info); |
717 | return root; | 717 | return root; |
718 | 718 | ||
719 | out_mountdata: | 719 | out_mountdata: |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 257f312ede42..8df28e925e5b 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -154,9 +154,9 @@ extern int set_cifs_acl(struct cifs_ntsd *, __u32, struct inode *, | |||
154 | extern void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, | 154 | extern void cifs_setup_cifs_sb(struct smb_vol *pvolume_info, |
155 | struct cifs_sb_info *cifs_sb); | 155 | struct cifs_sb_info *cifs_sb); |
156 | extern int cifs_match_super(struct super_block *, void *); | 156 | extern int cifs_match_super(struct super_block *, void *); |
157 | extern void cifs_cleanup_volume_info(struct smb_vol **pvolume_info); | 157 | extern void cifs_cleanup_volume_info(struct smb_vol *pvolume_info); |
158 | extern int cifs_setup_volume_info(struct smb_vol **pvolume_info, | 158 | extern struct smb_vol *cifs_get_volume_info(char *mount_data, |
159 | char *mount_data, const char *devname); | 159 | const char *devname); |
160 | extern int cifs_mount(struct cifs_sb_info *, struct smb_vol *); | 160 | extern int cifs_mount(struct cifs_sb_info *, struct smb_vol *); |
161 | extern void cifs_umount(struct cifs_sb_info *); | 161 | extern void cifs_umount(struct cifs_sb_info *); |
162 | extern void cifs_dfs_release_automount_timer(void); | 162 | extern void cifs_dfs_release_automount_timer(void); |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index c8cb83ef6f6f..dbd669cc5bc7 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -65,6 +65,8 @@ static int ip_connect(struct TCP_Server_Info *server); | |||
65 | static int generic_ip_connect(struct TCP_Server_Info *server); | 65 | static int generic_ip_connect(struct TCP_Server_Info *server); |
66 | static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink); | 66 | static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink); |
67 | static void cifs_prune_tlinks(struct work_struct *work); | 67 | static void cifs_prune_tlinks(struct work_struct *work); |
68 | static int cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data, | ||
69 | const char *devname); | ||
68 | 70 | ||
69 | /* | 71 | /* |
70 | * cifs tcp session reconnection | 72 | * cifs tcp session reconnection |
@@ -2240,8 +2242,8 @@ cifs_match_super(struct super_block *sb, void *data) | |||
2240 | 2242 | ||
2241 | rc = compare_mount_options(sb, mnt_data); | 2243 | rc = compare_mount_options(sb, mnt_data); |
2242 | out: | 2244 | out: |
2243 | cifs_put_tlink(tlink); | ||
2244 | spin_unlock(&cifs_tcp_ses_lock); | 2245 | spin_unlock(&cifs_tcp_ses_lock); |
2246 | cifs_put_tlink(tlink); | ||
2245 | return rc; | 2247 | return rc; |
2246 | } | 2248 | } |
2247 | 2249 | ||
@@ -2830,15 +2832,9 @@ is_path_accessible(int xid, struct cifs_tcon *tcon, | |||
2830 | return rc; | 2832 | return rc; |
2831 | } | 2833 | } |
2832 | 2834 | ||
2833 | void | 2835 | static void |
2834 | cifs_cleanup_volume_info(struct smb_vol **pvolume_info) | 2836 | cleanup_volume_info_contents(struct smb_vol *volume_info) |
2835 | { | 2837 | { |
2836 | struct smb_vol *volume_info; | ||
2837 | |||
2838 | if (!pvolume_info || !*pvolume_info) | ||
2839 | return; | ||
2840 | |||
2841 | volume_info = *pvolume_info; | ||
2842 | kfree(volume_info->username); | 2838 | kfree(volume_info->username); |
2843 | kzfree(volume_info->password); | 2839 | kzfree(volume_info->password); |
2844 | kfree(volume_info->UNC); | 2840 | kfree(volume_info->UNC); |
@@ -2846,28 +2842,44 @@ cifs_cleanup_volume_info(struct smb_vol **pvolume_info) | |||
2846 | kfree(volume_info->domainname); | 2842 | kfree(volume_info->domainname); |
2847 | kfree(volume_info->iocharset); | 2843 | kfree(volume_info->iocharset); |
2848 | kfree(volume_info->prepath); | 2844 | kfree(volume_info->prepath); |
2845 | } | ||
2846 | |||
2847 | void | ||
2848 | cifs_cleanup_volume_info(struct smb_vol *volume_info) | ||
2849 | { | ||
2850 | if (!volume_info) | ||
2851 | return; | ||
2852 | cleanup_volume_info_contents(volume_info); | ||
2849 | kfree(volume_info); | 2853 | kfree(volume_info); |
2850 | *pvolume_info = NULL; | ||
2851 | return; | ||
2852 | } | 2854 | } |
2853 | 2855 | ||
2856 | |||
2854 | #ifdef CONFIG_CIFS_DFS_UPCALL | 2857 | #ifdef CONFIG_CIFS_DFS_UPCALL |
2855 | /* build_path_to_root returns full path to root when | 2858 | /* build_path_to_root returns full path to root when |
2856 | * we do not have an exiting connection (tcon) */ | 2859 | * we do not have an exiting connection (tcon) */ |
2857 | static char * | 2860 | static char * |
2858 | build_unc_path_to_root(const struct smb_vol *volume_info, | 2861 | build_unc_path_to_root(const struct smb_vol *vol, |
2859 | const struct cifs_sb_info *cifs_sb) | 2862 | const struct cifs_sb_info *cifs_sb) |
2860 | { | 2863 | { |
2861 | char *full_path; | 2864 | char *full_path, *pos; |
2865 | unsigned int pplen = vol->prepath ? strlen(vol->prepath) : 0; | ||
2866 | unsigned int unc_len = strnlen(vol->UNC, MAX_TREE_SIZE + 1); | ||
2862 | 2867 | ||
2863 | int unc_len = strnlen(volume_info->UNC, MAX_TREE_SIZE + 1); | 2868 | full_path = kmalloc(unc_len + pplen + 1, GFP_KERNEL); |
2864 | full_path = kmalloc(unc_len + 1, GFP_KERNEL); | ||
2865 | if (full_path == NULL) | 2869 | if (full_path == NULL) |
2866 | return ERR_PTR(-ENOMEM); | 2870 | return ERR_PTR(-ENOMEM); |
2867 | 2871 | ||
2868 | strncpy(full_path, volume_info->UNC, unc_len); | 2872 | strncpy(full_path, vol->UNC, unc_len); |
2869 | full_path[unc_len] = 0; /* add trailing null */ | 2873 | pos = full_path + unc_len; |
2874 | |||
2875 | if (pplen) { | ||
2876 | strncpy(pos, vol->prepath, pplen); | ||
2877 | pos += pplen; | ||
2878 | } | ||
2879 | |||
2880 | *pos = '\0'; /* add trailing null */ | ||
2870 | convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb)); | 2881 | convert_delimiter(full_path, CIFS_DIR_SEP(cifs_sb)); |
2882 | cFYI(1, "%s: full_path=%s", __func__, full_path); | ||
2871 | return full_path; | 2883 | return full_path; |
2872 | } | 2884 | } |
2873 | 2885 | ||
@@ -2910,15 +2922,18 @@ expand_dfs_referral(int xid, struct cifs_ses *pSesInfo, | |||
2910 | &fake_devname); | 2922 | &fake_devname); |
2911 | 2923 | ||
2912 | free_dfs_info_array(referrals, num_referrals); | 2924 | free_dfs_info_array(referrals, num_referrals); |
2913 | kfree(fake_devname); | ||
2914 | |||
2915 | if (cifs_sb->mountdata != NULL) | ||
2916 | kfree(cifs_sb->mountdata); | ||
2917 | 2925 | ||
2918 | if (IS_ERR(mdata)) { | 2926 | if (IS_ERR(mdata)) { |
2919 | rc = PTR_ERR(mdata); | 2927 | rc = PTR_ERR(mdata); |
2920 | mdata = NULL; | 2928 | mdata = NULL; |
2929 | } else { | ||
2930 | cleanup_volume_info_contents(volume_info); | ||
2931 | memset(volume_info, '\0', sizeof(*volume_info)); | ||
2932 | rc = cifs_setup_volume_info(volume_info, mdata, | ||
2933 | fake_devname); | ||
2921 | } | 2934 | } |
2935 | kfree(fake_devname); | ||
2936 | kfree(cifs_sb->mountdata); | ||
2922 | cifs_sb->mountdata = mdata; | 2937 | cifs_sb->mountdata = mdata; |
2923 | } | 2938 | } |
2924 | kfree(full_path); | 2939 | kfree(full_path); |
@@ -2926,33 +2941,20 @@ expand_dfs_referral(int xid, struct cifs_ses *pSesInfo, | |||
2926 | } | 2941 | } |
2927 | #endif | 2942 | #endif |
2928 | 2943 | ||
2929 | int cifs_setup_volume_info(struct smb_vol **pvolume_info, char *mount_data, | 2944 | static int |
2930 | const char *devname) | 2945 | cifs_setup_volume_info(struct smb_vol *volume_info, char *mount_data, |
2946 | const char *devname) | ||
2931 | { | 2947 | { |
2932 | struct smb_vol *volume_info; | ||
2933 | int rc = 0; | 2948 | int rc = 0; |
2934 | 2949 | ||
2935 | *pvolume_info = NULL; | 2950 | if (cifs_parse_mount_options(mount_data, devname, volume_info)) |
2936 | 2951 | return -EINVAL; | |
2937 | volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL); | ||
2938 | if (!volume_info) { | ||
2939 | rc = -ENOMEM; | ||
2940 | goto out; | ||
2941 | } | ||
2942 | |||
2943 | if (cifs_parse_mount_options(mount_data, devname, | ||
2944 | volume_info)) { | ||
2945 | rc = -EINVAL; | ||
2946 | goto out; | ||
2947 | } | ||
2948 | 2952 | ||
2949 | if (volume_info->nullauth) { | 2953 | if (volume_info->nullauth) { |
2950 | cFYI(1, "null user"); | 2954 | cFYI(1, "null user"); |
2951 | volume_info->username = kzalloc(1, GFP_KERNEL); | 2955 | volume_info->username = kzalloc(1, GFP_KERNEL); |
2952 | if (volume_info->username == NULL) { | 2956 | if (volume_info->username == NULL) |
2953 | rc = -ENOMEM; | 2957 | return -ENOMEM; |
2954 | goto out; | ||
2955 | } | ||
2956 | } else if (volume_info->username) { | 2958 | } else if (volume_info->username) { |
2957 | /* BB fixme parse for domain name here */ | 2959 | /* BB fixme parse for domain name here */ |
2958 | cFYI(1, "Username: %s", volume_info->username); | 2960 | cFYI(1, "Username: %s", volume_info->username); |
@@ -2960,8 +2962,7 @@ int cifs_setup_volume_info(struct smb_vol **pvolume_info, char *mount_data, | |||
2960 | cifserror("No username specified"); | 2962 | cifserror("No username specified"); |
2961 | /* In userspace mount helper we can get user name from alternate | 2963 | /* In userspace mount helper we can get user name from alternate |
2962 | locations such as env variables and files on disk */ | 2964 | locations such as env variables and files on disk */ |
2963 | rc = -EINVAL; | 2965 | return -EINVAL; |
2964 | goto out; | ||
2965 | } | 2966 | } |
2966 | 2967 | ||
2967 | /* this is needed for ASCII cp to Unicode converts */ | 2968 | /* this is needed for ASCII cp to Unicode converts */ |
@@ -2973,18 +2974,32 @@ int cifs_setup_volume_info(struct smb_vol **pvolume_info, char *mount_data, | |||
2973 | if (volume_info->local_nls == NULL) { | 2974 | if (volume_info->local_nls == NULL) { |
2974 | cERROR(1, "CIFS mount error: iocharset %s not found", | 2975 | cERROR(1, "CIFS mount error: iocharset %s not found", |
2975 | volume_info->iocharset); | 2976 | volume_info->iocharset); |
2976 | rc = -ELIBACC; | 2977 | return -ELIBACC; |
2977 | goto out; | ||
2978 | } | 2978 | } |
2979 | } | 2979 | } |
2980 | 2980 | ||
2981 | *pvolume_info = volume_info; | ||
2982 | return rc; | ||
2983 | out: | ||
2984 | cifs_cleanup_volume_info(&volume_info); | ||
2985 | return rc; | 2981 | return rc; |
2986 | } | 2982 | } |
2987 | 2983 | ||
2984 | struct smb_vol * | ||
2985 | cifs_get_volume_info(char *mount_data, const char *devname) | ||
2986 | { | ||
2987 | int rc; | ||
2988 | struct smb_vol *volume_info; | ||
2989 | |||
2990 | volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL); | ||
2991 | if (!volume_info) | ||
2992 | return ERR_PTR(-ENOMEM); | ||
2993 | |||
2994 | rc = cifs_setup_volume_info(volume_info, mount_data, devname); | ||
2995 | if (rc) { | ||
2996 | cifs_cleanup_volume_info(volume_info); | ||
2997 | volume_info = ERR_PTR(rc); | ||
2998 | } | ||
2999 | |||
3000 | return volume_info; | ||
3001 | } | ||
3002 | |||
2988 | int | 3003 | int |
2989 | cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) | 3004 | cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) |
2990 | { | 3005 | { |
@@ -2997,6 +3012,7 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) | |||
2997 | struct tcon_link *tlink; | 3012 | struct tcon_link *tlink; |
2998 | #ifdef CONFIG_CIFS_DFS_UPCALL | 3013 | #ifdef CONFIG_CIFS_DFS_UPCALL |
2999 | int referral_walks_count = 0; | 3014 | int referral_walks_count = 0; |
3015 | #endif | ||
3000 | 3016 | ||
3001 | rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); | 3017 | rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); |
3002 | if (rc) | 3018 | if (rc) |
@@ -3004,6 +3020,7 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info) | |||
3004 | 3020 | ||
3005 | cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages; | 3021 | cifs_sb->bdi.ra_pages = default_backing_dev_info.ra_pages; |
3006 | 3022 | ||
3023 | #ifdef CONFIG_CIFS_DFS_UPCALL | ||
3007 | try_mount_again: | 3024 | try_mount_again: |
3008 | /* cleanup activities if we're chasing a referral */ | 3025 | /* cleanup activities if we're chasing a referral */ |
3009 | if (referral_walks_count) { | 3026 | if (referral_walks_count) { |
@@ -3012,7 +3029,6 @@ try_mount_again: | |||
3012 | else if (pSesInfo) | 3029 | else if (pSesInfo) |
3013 | cifs_put_smb_ses(pSesInfo); | 3030 | cifs_put_smb_ses(pSesInfo); |
3014 | 3031 | ||
3015 | cifs_cleanup_volume_info(&volume_info); | ||
3016 | FreeXid(xid); | 3032 | FreeXid(xid); |
3017 | } | 3033 | } |
3018 | #endif | 3034 | #endif |
diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c index 816696621ec9..42e5363b4102 100644 --- a/fs/cifs/fscache.c +++ b/fs/cifs/fscache.c | |||
@@ -92,6 +92,7 @@ static void cifs_fscache_disable_inode_cookie(struct inode *inode) | |||
92 | 92 | ||
93 | if (cifsi->fscache) { | 93 | if (cifsi->fscache) { |
94 | cFYI(1, "%s: (0x%p)", __func__, cifsi->fscache); | 94 | cFYI(1, "%s: (0x%p)", __func__, cifsi->fscache); |
95 | fscache_uncache_all_inode_pages(cifsi->fscache, inode); | ||
95 | fscache_relinquish_cookie(cifsi->fscache, 1); | 96 | fscache_relinquish_cookie(cifsi->fscache, 1); |
96 | cifsi->fscache = NULL; | 97 | cifsi->fscache = NULL; |
97 | } | 98 | } |
diff --git a/fs/fscache/page.c b/fs/fscache/page.c index a2a5d19ece6a..2f343b4d7a7d 100644 --- a/fs/fscache/page.c +++ b/fs/fscache/page.c | |||
@@ -954,3 +954,47 @@ void fscache_mark_pages_cached(struct fscache_retrieval *op, | |||
954 | pagevec_reinit(pagevec); | 954 | pagevec_reinit(pagevec); |
955 | } | 955 | } |
956 | EXPORT_SYMBOL(fscache_mark_pages_cached); | 956 | EXPORT_SYMBOL(fscache_mark_pages_cached); |
957 | |||
958 | /* | ||
959 | * Uncache all the pages in an inode that are marked PG_fscache, assuming them | ||
960 | * to be associated with the given cookie. | ||
961 | */ | ||
962 | void __fscache_uncache_all_inode_pages(struct fscache_cookie *cookie, | ||
963 | struct inode *inode) | ||
964 | { | ||
965 | struct address_space *mapping = inode->i_mapping; | ||
966 | struct pagevec pvec; | ||
967 | pgoff_t next; | ||
968 | int i; | ||
969 | |||
970 | _enter("%p,%p", cookie, inode); | ||
971 | |||
972 | if (!mapping || mapping->nrpages == 0) { | ||
973 | _leave(" [no pages]"); | ||
974 | return; | ||
975 | } | ||
976 | |||
977 | pagevec_init(&pvec, 0); | ||
978 | next = 0; | ||
979 | while (next <= (loff_t)-1 && | ||
980 | pagevec_lookup(&pvec, mapping, next, PAGEVEC_SIZE) | ||
981 | ) { | ||
982 | for (i = 0; i < pagevec_count(&pvec); i++) { | ||
983 | struct page *page = pvec.pages[i]; | ||
984 | pgoff_t page_index = page->index; | ||
985 | |||
986 | ASSERTCMP(page_index, >=, next); | ||
987 | next = page_index + 1; | ||
988 | |||
989 | if (PageFsCache(page)) { | ||
990 | __fscache_wait_on_page_write(cookie, page); | ||
991 | __fscache_uncache_page(cookie, page); | ||
992 | } | ||
993 | } | ||
994 | pagevec_release(&pvec); | ||
995 | cond_resched(); | ||
996 | } | ||
997 | |||
998 | _leave(""); | ||
999 | } | ||
1000 | EXPORT_SYMBOL(__fscache_uncache_all_inode_pages); | ||
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c index b49b55584c84..84a47b709f51 100644 --- a/fs/hfsplus/super.c +++ b/fs/hfsplus/super.c | |||
@@ -500,7 +500,7 @@ static int hfsplus_fill_super(struct super_block *sb, void *data, int silent) | |||
500 | out_put_hidden_dir: | 500 | out_put_hidden_dir: |
501 | iput(sbi->hidden_dir); | 501 | iput(sbi->hidden_dir); |
502 | out_put_root: | 502 | out_put_root: |
503 | iput(sbi->alloc_file); | 503 | iput(root); |
504 | out_put_alloc_file: | 504 | out_put_alloc_file: |
505 | iput(sbi->alloc_file); | 505 | iput(sbi->alloc_file); |
506 | out_close_cat_tree: | 506 | out_close_cat_tree: |
diff --git a/fs/hfsplus/wrapper.c b/fs/hfsplus/wrapper.c index 3031d81f5f0f..4ac88ff79aa6 100644 --- a/fs/hfsplus/wrapper.c +++ b/fs/hfsplus/wrapper.c | |||
@@ -36,6 +36,7 @@ int hfsplus_submit_bio(struct block_device *bdev, sector_t sector, | |||
36 | { | 36 | { |
37 | DECLARE_COMPLETION_ONSTACK(wait); | 37 | DECLARE_COMPLETION_ONSTACK(wait); |
38 | struct bio *bio; | 38 | struct bio *bio; |
39 | int ret = 0; | ||
39 | 40 | ||
40 | bio = bio_alloc(GFP_NOIO, 1); | 41 | bio = bio_alloc(GFP_NOIO, 1); |
41 | bio->bi_sector = sector; | 42 | bio->bi_sector = sector; |
@@ -54,8 +55,10 @@ int hfsplus_submit_bio(struct block_device *bdev, sector_t sector, | |||
54 | wait_for_completion(&wait); | 55 | wait_for_completion(&wait); |
55 | 56 | ||
56 | if (!bio_flagged(bio, BIO_UPTODATE)) | 57 | if (!bio_flagged(bio, BIO_UPTODATE)) |
57 | return -EIO; | 58 | ret = -EIO; |
58 | return 0; | 59 | |
60 | bio_put(bio); | ||
61 | return ret; | ||
59 | } | 62 | } |
60 | 63 | ||
61 | static int hfsplus_read_mdb(void *bufptr, struct hfsplus_wd *wd) | 64 | static int hfsplus_read_mdb(void *bufptr, struct hfsplus_wd *wd) |
diff --git a/fs/locks.c b/fs/locks.c index 0a4f50dfadfb..b286539d547a 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -160,10 +160,28 @@ EXPORT_SYMBOL_GPL(unlock_flocks); | |||
160 | 160 | ||
161 | static struct kmem_cache *filelock_cache __read_mostly; | 161 | static struct kmem_cache *filelock_cache __read_mostly; |
162 | 162 | ||
163 | static void locks_init_lock_always(struct file_lock *fl) | ||
164 | { | ||
165 | fl->fl_next = NULL; | ||
166 | fl->fl_fasync = NULL; | ||
167 | fl->fl_owner = NULL; | ||
168 | fl->fl_pid = 0; | ||
169 | fl->fl_nspid = NULL; | ||
170 | fl->fl_file = NULL; | ||
171 | fl->fl_flags = 0; | ||
172 | fl->fl_type = 0; | ||
173 | fl->fl_start = fl->fl_end = 0; | ||
174 | } | ||
175 | |||
163 | /* Allocate an empty lock structure. */ | 176 | /* Allocate an empty lock structure. */ |
164 | struct file_lock *locks_alloc_lock(void) | 177 | struct file_lock *locks_alloc_lock(void) |
165 | { | 178 | { |
166 | return kmem_cache_alloc(filelock_cache, GFP_KERNEL); | 179 | struct file_lock *fl = kmem_cache_alloc(filelock_cache, GFP_KERNEL); |
180 | |||
181 | if (fl) | ||
182 | locks_init_lock_always(fl); | ||
183 | |||
184 | return fl; | ||
167 | } | 185 | } |
168 | EXPORT_SYMBOL_GPL(locks_alloc_lock); | 186 | EXPORT_SYMBOL_GPL(locks_alloc_lock); |
169 | 187 | ||
@@ -200,17 +218,9 @@ void locks_init_lock(struct file_lock *fl) | |||
200 | INIT_LIST_HEAD(&fl->fl_link); | 218 | INIT_LIST_HEAD(&fl->fl_link); |
201 | INIT_LIST_HEAD(&fl->fl_block); | 219 | INIT_LIST_HEAD(&fl->fl_block); |
202 | init_waitqueue_head(&fl->fl_wait); | 220 | init_waitqueue_head(&fl->fl_wait); |
203 | fl->fl_next = NULL; | ||
204 | fl->fl_fasync = NULL; | ||
205 | fl->fl_owner = NULL; | ||
206 | fl->fl_pid = 0; | ||
207 | fl->fl_nspid = NULL; | ||
208 | fl->fl_file = NULL; | ||
209 | fl->fl_flags = 0; | ||
210 | fl->fl_type = 0; | ||
211 | fl->fl_start = fl->fl_end = 0; | ||
212 | fl->fl_ops = NULL; | 221 | fl->fl_ops = NULL; |
213 | fl->fl_lmops = NULL; | 222 | fl->fl_lmops = NULL; |
223 | locks_init_lock_always(fl); | ||
214 | } | 224 | } |
215 | 225 | ||
216 | EXPORT_SYMBOL(locks_init_lock); | 226 | EXPORT_SYMBOL(locks_init_lock); |
diff --git a/fs/nfs/fscache.c b/fs/nfs/fscache.c index ce153a6b3aec..419119c371bf 100644 --- a/fs/nfs/fscache.c +++ b/fs/nfs/fscache.c | |||
@@ -259,12 +259,10 @@ static void nfs_fscache_disable_inode_cookie(struct inode *inode) | |||
259 | dfprintk(FSCACHE, | 259 | dfprintk(FSCACHE, |
260 | "NFS: nfsi 0x%p turning cache off\n", NFS_I(inode)); | 260 | "NFS: nfsi 0x%p turning cache off\n", NFS_I(inode)); |
261 | 261 | ||
262 | /* Need to invalidate any mapped pages that were read in before | 262 | /* Need to uncache any pages attached to this inode that |
263 | * turning off the cache. | 263 | * fscache knows about before turning off the cache. |
264 | */ | 264 | */ |
265 | if (inode->i_mapping && inode->i_mapping->nrpages) | 265 | fscache_uncache_all_inode_pages(NFS_I(inode)->fscache, inode); |
266 | invalidate_inode_pages2(inode->i_mapping); | ||
267 | |||
268 | nfs_fscache_zap_inode_cookie(inode); | 266 | nfs_fscache_zap_inode_cookie(inode); |
269 | } | 267 | } |
270 | } | 268 | } |
diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 09983a3344a5..b1e88d56069c 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c | |||
@@ -681,15 +681,15 @@ xfs_inode_item_unlock( | |||
681 | * where the cluster buffer may be unpinned before the inode is inserted into | 681 | * where the cluster buffer may be unpinned before the inode is inserted into |
682 | * the AIL during transaction committed processing. If the buffer is unpinned | 682 | * the AIL during transaction committed processing. If the buffer is unpinned |
683 | * before the inode item has been committed and inserted, then it is possible | 683 | * before the inode item has been committed and inserted, then it is possible |
684 | * for the buffer to be written and IO completions before the inode is inserted | 684 | * for the buffer to be written and IO completes before the inode is inserted |
685 | * into the AIL. In that case, we'd be inserting a clean, stale inode into the | 685 | * into the AIL. In that case, we'd be inserting a clean, stale inode into the |
686 | * AIL which will never get removed. It will, however, get reclaimed which | 686 | * AIL which will never get removed. It will, however, get reclaimed which |
687 | * triggers an assert in xfs_inode_free() complaining about freein an inode | 687 | * triggers an assert in xfs_inode_free() complaining about freein an inode |
688 | * still in the AIL. | 688 | * still in the AIL. |
689 | * | 689 | * |
690 | * To avoid this, return a lower LSN than the one passed in so that the | 690 | * To avoid this, just unpin the inode directly and return a LSN of -1 so the |
691 | * transaction committed code will not move the inode forward in the AIL but | 691 | * transaction committed code knows that it does not need to do any further |
692 | * will still unpin it properly. | 692 | * processing on the item. |
693 | */ | 693 | */ |
694 | STATIC xfs_lsn_t | 694 | STATIC xfs_lsn_t |
695 | xfs_inode_item_committed( | 695 | xfs_inode_item_committed( |
@@ -699,8 +699,10 @@ xfs_inode_item_committed( | |||
699 | struct xfs_inode_log_item *iip = INODE_ITEM(lip); | 699 | struct xfs_inode_log_item *iip = INODE_ITEM(lip); |
700 | struct xfs_inode *ip = iip->ili_inode; | 700 | struct xfs_inode *ip = iip->ili_inode; |
701 | 701 | ||
702 | if (xfs_iflags_test(ip, XFS_ISTALE)) | 702 | if (xfs_iflags_test(ip, XFS_ISTALE)) { |
703 | return lsn - 1; | 703 | xfs_inode_item_unpin(lip, 0); |
704 | return -1; | ||
705 | } | ||
704 | return lsn; | 706 | return lsn; |
705 | } | 707 | } |
706 | 708 | ||
diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index 7c7bc2b786bd..c83f63b33aae 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c | |||
@@ -1361,7 +1361,7 @@ xfs_trans_item_committed( | |||
1361 | lip->li_flags |= XFS_LI_ABORTED; | 1361 | lip->li_flags |= XFS_LI_ABORTED; |
1362 | item_lsn = IOP_COMMITTED(lip, commit_lsn); | 1362 | item_lsn = IOP_COMMITTED(lip, commit_lsn); |
1363 | 1363 | ||
1364 | /* If the committed routine returns -1, item has been freed. */ | 1364 | /* item_lsn of -1 means the item needs no further processing */ |
1365 | if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0) | 1365 | if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0) |
1366 | return; | 1366 | return; |
1367 | 1367 | ||
@@ -1474,7 +1474,7 @@ xfs_trans_committed_bulk( | |||
1474 | lip->li_flags |= XFS_LI_ABORTED; | 1474 | lip->li_flags |= XFS_LI_ABORTED; |
1475 | item_lsn = IOP_COMMITTED(lip, commit_lsn); | 1475 | item_lsn = IOP_COMMITTED(lip, commit_lsn); |
1476 | 1476 | ||
1477 | /* item_lsn of -1 means the item was freed */ | 1477 | /* item_lsn of -1 means the item needs no further processing */ |
1478 | if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0) | 1478 | if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0) |
1479 | continue; | 1479 | continue; |
1480 | 1480 | ||