aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ntfs/lcnalloc.c
diff options
context:
space:
mode:
authorAnton Altaparmakov <aia21@cantab.net>2005-02-15 05:08:43 -0500
committerAnton Altaparmakov <aia21@cantab.net>2005-05-05 05:56:31 -0400
commitb6ad6c52fe36ab35d0fe28c064f59de2ba670c2a (patch)
treed888c28a2c3c7fa733045dc7dc9c9bc7f157bf4a /fs/ntfs/lcnalloc.c
parent1a0df15acdae065789446aca83021c72b71db9a5 (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.c39
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;
977unl_err_out:
978 up_read(&ni->runlist.lock);
979err_out: 963err_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. */