diff options
author | Anton Altaparmakov <aia21@cantab.net> | 2005-02-15 05:08:43 -0500 |
---|---|---|
committer | Anton Altaparmakov <aia21@cantab.net> | 2005-05-05 05:56:31 -0400 |
commit | b6ad6c52fe36ab35d0fe28c064f59de2ba670c2a (patch) | |
tree | d888c28a2c3c7fa733045dc7dc9c9bc7f157bf4a /fs/ntfs/lcnalloc.c | |
parent | 1a0df15acdae065789446aca83021c72b71db9a5 (diff) |
NTFS: - Split ntfs_map_runlist() into ntfs_map_runlist() and a non-locking
helper ntfs_map_runlist_nolock() which is used by ntfs_map_runlist().
This allows us to map runlist fragments with the runlist lock already
held without having to drop and reacquire it around the call. Adapt
all callers.
- Change ntfs_find_vcn() to ntfs_find_vcn_nolock() which takes a locked
runlist. This allows us to find runlist elements with the runlist
lock already held without having to drop and reacquire it around the
call. Adapt all callers.
Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
Diffstat (limited to 'fs/ntfs/lcnalloc.c')
-rw-r--r-- | fs/ntfs/lcnalloc.c | 39 |
1 files changed, 12 insertions, 27 deletions
diff --git a/fs/ntfs/lcnalloc.c b/fs/ntfs/lcnalloc.c index 5346596fa871..8db4492b139c 100644 --- a/fs/ntfs/lcnalloc.c +++ b/fs/ntfs/lcnalloc.c | |||
@@ -849,7 +849,8 @@ s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count, | |||
849 | total_freed = real_freed = 0; | 849 | total_freed = real_freed = 0; |
850 | 850 | ||
851 | /* This returns with ni->runlist locked for reading on success. */ | 851 | /* This returns with ni->runlist locked for reading on success. */ |
852 | rl = ntfs_find_vcn(ni, start_vcn, FALSE); | 852 | down_read(&ni->runlist.lock); |
853 | rl = ntfs_find_vcn_nolock(ni, start_vcn, FALSE); | ||
853 | if (IS_ERR(rl)) { | 854 | if (IS_ERR(rl)) { |
854 | if (!is_rollback) | 855 | if (!is_rollback) |
855 | ntfs_error(vol->sb, "Failed to find first runlist " | 856 | ntfs_error(vol->sb, "Failed to find first runlist " |
@@ -863,7 +864,7 @@ s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count, | |||
863 | ntfs_error(vol->sb, "First runlist element has " | 864 | ntfs_error(vol->sb, "First runlist element has " |
864 | "invalid lcn, aborting."); | 865 | "invalid lcn, aborting."); |
865 | err = -EIO; | 866 | err = -EIO; |
866 | goto unl_err_out; | 867 | goto err_out; |
867 | } | 868 | } |
868 | /* Find the starting cluster inside the run that needs freeing. */ | 869 | /* Find the starting cluster inside the run that needs freeing. */ |
869 | delta = start_vcn - rl->vcn; | 870 | delta = start_vcn - rl->vcn; |
@@ -881,7 +882,7 @@ s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count, | |||
881 | if (!is_rollback) | 882 | if (!is_rollback) |
882 | ntfs_error(vol->sb, "Failed to clear first run " | 883 | ntfs_error(vol->sb, "Failed to clear first run " |
883 | "(error %i), aborting.", err); | 884 | "(error %i), aborting.", err); |
884 | goto unl_err_out; | 885 | goto err_out; |
885 | } | 886 | } |
886 | /* We have freed @to_free real clusters. */ | 887 | /* We have freed @to_free real clusters. */ |
887 | real_freed = to_free; | 888 | real_freed = to_free; |
@@ -901,30 +902,15 @@ s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count, | |||
901 | if (unlikely(rl->lcn < LCN_HOLE)) { | 902 | if (unlikely(rl->lcn < LCN_HOLE)) { |
902 | VCN vcn; | 903 | VCN vcn; |
903 | 904 | ||
904 | /* | 905 | /* Attempt to map runlist. */ |
905 | * Attempt to map runlist, dropping runlist lock for | ||
906 | * the duration. | ||
907 | */ | ||
908 | vcn = rl->vcn; | 906 | vcn = rl->vcn; |
909 | up_read(&ni->runlist.lock); | 907 | rl = ntfs_find_vcn_nolock(ni, vcn, FALSE); |
910 | err = ntfs_map_runlist(ni, vcn); | ||
911 | if (err) { | ||
912 | if (!is_rollback) | ||
913 | ntfs_error(vol->sb, "Failed to map " | ||
914 | "runlist fragment."); | ||
915 | if (err == -EINVAL || err == -ENOENT) | ||
916 | err = -EIO; | ||
917 | goto err_out; | ||
918 | } | ||
919 | /* | ||
920 | * This returns with ni->runlist locked for reading on | ||
921 | * success. | ||
922 | */ | ||
923 | rl = ntfs_find_vcn(ni, vcn, FALSE); | ||
924 | if (IS_ERR(rl)) { | 908 | if (IS_ERR(rl)) { |
925 | err = PTR_ERR(rl); | 909 | err = PTR_ERR(rl); |
926 | if (!is_rollback) | 910 | if (!is_rollback) |
927 | ntfs_error(vol->sb, "Failed to find " | 911 | ntfs_error(vol->sb, "Failed to map " |
912 | "runlist fragment or " | ||
913 | "failed to find " | ||
928 | "subsequent runlist " | 914 | "subsequent runlist " |
929 | "element."); | 915 | "element."); |
930 | goto err_out; | 916 | goto err_out; |
@@ -937,7 +923,7 @@ s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count, | |||
937 | (unsigned long long) | 923 | (unsigned long long) |
938 | rl->lcn); | 924 | rl->lcn); |
939 | err = -EIO; | 925 | err = -EIO; |
940 | goto unl_err_out; | 926 | goto err_out; |
941 | } | 927 | } |
942 | } | 928 | } |
943 | /* The number of clusters in this run that need freeing. */ | 929 | /* The number of clusters in this run that need freeing. */ |
@@ -953,7 +939,7 @@ s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count, | |||
953 | if (!is_rollback) | 939 | if (!is_rollback) |
954 | ntfs_error(vol->sb, "Failed to clear " | 940 | ntfs_error(vol->sb, "Failed to clear " |
955 | "subsequent run."); | 941 | "subsequent run."); |
956 | goto unl_err_out; | 942 | goto err_out; |
957 | } | 943 | } |
958 | /* We have freed @to_free real clusters. */ | 944 | /* We have freed @to_free real clusters. */ |
959 | real_freed += to_free; | 945 | real_freed += to_free; |
@@ -974,9 +960,8 @@ s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count, | |||
974 | /* We are done. Return the number of actually freed clusters. */ | 960 | /* We are done. Return the number of actually freed clusters. */ |
975 | ntfs_debug("Done."); | 961 | ntfs_debug("Done."); |
976 | return real_freed; | 962 | return real_freed; |
977 | unl_err_out: | ||
978 | up_read(&ni->runlist.lock); | ||
979 | err_out: | 963 | err_out: |
964 | up_read(&ni->runlist.lock); | ||
980 | if (is_rollback) | 965 | if (is_rollback) |
981 | return err; | 966 | return err; |
982 | /* If no real clusters were freed, no need to rollback. */ | 967 | /* If no real clusters were freed, no need to rollback. */ |