diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-28 13:00:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-28 13:00:14 -0400 |
commit | 9a7259d5c8978bbeb5fdcf64b168f8470d8208a6 (patch) | |
tree | 5c255d4b18622de06c2637c0c4069a384e99466d | |
parent | e9c0f1529c9022afbab16a442382aa9a84a79c41 (diff) | |
parent | e703c206135acb458adb705ec44bcc5d2615b37d (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull ext3, UDF, and quota fixes from Jan Kara:
"A couple of ext3 & UDF fixes and also one improvement in quota
locking."
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs:
ext3: fix start and len arguments handling in ext3_trim_fs()
udf: Fix deadlock in udf_release_file()
udf: Fix file entry logicalBlocksRecorded
udf: Fix handling of i_blocks
quota: Make quota code not call tty layer with dqptr_sem held
udf: Init/maintain file entry checkpoint field
ext3: Update ctime in ext3_splice_branch() only when needed
ext3: Don't call dquot_free_block() if we don't update anything
udf: Remove unnecessary OOM messages
-rw-r--r-- | fs/ext3/balloc.c | 84 | ||||
-rw-r--r-- | fs/ext3/inode.c | 9 | ||||
-rw-r--r-- | fs/quota/dquot.c | 189 | ||||
-rw-r--r-- | fs/udf/balloc.c | 84 | ||||
-rw-r--r-- | fs/udf/ialloc.c | 1 | ||||
-rw-r--r-- | fs/udf/inode.c | 20 | ||||
-rw-r--r-- | fs/udf/super.c | 5 | ||||
-rw-r--r-- | fs/udf/udf_i.h | 1 |
8 files changed, 226 insertions, 167 deletions
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c index a2038928f9a3..1e036b79384c 100644 --- a/fs/ext3/balloc.c +++ b/fs/ext3/balloc.c | |||
@@ -1743,8 +1743,11 @@ allocated: | |||
1743 | 1743 | ||
1744 | *errp = 0; | 1744 | *errp = 0; |
1745 | brelse(bitmap_bh); | 1745 | brelse(bitmap_bh); |
1746 | dquot_free_block(inode, *count-num); | 1746 | |
1747 | *count = num; | 1747 | if (num < *count) { |
1748 | dquot_free_block(inode, *count-num); | ||
1749 | *count = num; | ||
1750 | } | ||
1748 | 1751 | ||
1749 | trace_ext3_allocate_blocks(inode, goal, num, | 1752 | trace_ext3_allocate_blocks(inode, goal, num, |
1750 | (unsigned long long)ret_block); | 1753 | (unsigned long long)ret_block); |
@@ -1970,7 +1973,7 @@ static ext3_grpblk_t ext3_trim_all_free(struct super_block *sb, | |||
1970 | sbi = EXT3_SB(sb); | 1973 | sbi = EXT3_SB(sb); |
1971 | 1974 | ||
1972 | /* Walk through the whole group */ | 1975 | /* Walk through the whole group */ |
1973 | while (start < max) { | 1976 | while (start <= max) { |
1974 | start = bitmap_search_next_usable_block(start, bitmap_bh, max); | 1977 | start = bitmap_search_next_usable_block(start, bitmap_bh, max); |
1975 | if (start < 0) | 1978 | if (start < 0) |
1976 | break; | 1979 | break; |
@@ -1980,7 +1983,7 @@ static ext3_grpblk_t ext3_trim_all_free(struct super_block *sb, | |||
1980 | * Allocate contiguous free extents by setting bits in the | 1983 | * Allocate contiguous free extents by setting bits in the |
1981 | * block bitmap | 1984 | * block bitmap |
1982 | */ | 1985 | */ |
1983 | while (next < max | 1986 | while (next <= max |
1984 | && claim_block(sb_bgl_lock(sbi, group), | 1987 | && claim_block(sb_bgl_lock(sbi, group), |
1985 | next, bitmap_bh)) { | 1988 | next, bitmap_bh)) { |
1986 | next++; | 1989 | next++; |
@@ -2091,73 +2094,74 @@ err_out: | |||
2091 | */ | 2094 | */ |
2092 | int ext3_trim_fs(struct super_block *sb, struct fstrim_range *range) | 2095 | int ext3_trim_fs(struct super_block *sb, struct fstrim_range *range) |
2093 | { | 2096 | { |
2094 | ext3_grpblk_t last_block, first_block, free_blocks; | 2097 | ext3_grpblk_t last_block, first_block; |
2095 | unsigned long first_group, last_group; | 2098 | unsigned long group, first_group, last_group; |
2096 | unsigned long group, ngroups; | ||
2097 | struct ext3_group_desc *gdp; | 2099 | struct ext3_group_desc *gdp; |
2098 | struct ext3_super_block *es = EXT3_SB(sb)->s_es; | 2100 | struct ext3_super_block *es = EXT3_SB(sb)->s_es; |
2099 | uint64_t start, len, minlen, trimmed; | 2101 | uint64_t start, minlen, end, trimmed = 0; |
2102 | ext3_fsblk_t first_data_blk = | ||
2103 | le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block); | ||
2100 | ext3_fsblk_t max_blks = le32_to_cpu(es->s_blocks_count); | 2104 | ext3_fsblk_t max_blks = le32_to_cpu(es->s_blocks_count); |
2101 | int ret = 0; | 2105 | int ret = 0; |
2102 | 2106 | ||
2103 | start = (range->start >> sb->s_blocksize_bits) + | 2107 | start = range->start >> sb->s_blocksize_bits; |
2104 | le32_to_cpu(es->s_first_data_block); | 2108 | end = start + (range->len >> sb->s_blocksize_bits) - 1; |
2105 | len = range->len >> sb->s_blocksize_bits; | ||
2106 | minlen = range->minlen >> sb->s_blocksize_bits; | 2109 | minlen = range->minlen >> sb->s_blocksize_bits; |
2107 | trimmed = 0; | ||
2108 | 2110 | ||
2109 | if (unlikely(minlen > EXT3_BLOCKS_PER_GROUP(sb))) | 2111 | if (unlikely(minlen > EXT3_BLOCKS_PER_GROUP(sb)) || |
2112 | unlikely(start >= max_blks)) | ||
2110 | return -EINVAL; | 2113 | return -EINVAL; |
2111 | if (start >= max_blks) | 2114 | if (end >= max_blks) |
2112 | return -EINVAL; | 2115 | end = max_blks - 1; |
2113 | if (start + len > max_blks) | 2116 | if (end <= first_data_blk) |
2114 | len = max_blks - start; | 2117 | goto out; |
2118 | if (start < first_data_blk) | ||
2119 | start = first_data_blk; | ||
2115 | 2120 | ||
2116 | ngroups = EXT3_SB(sb)->s_groups_count; | ||
2117 | smp_rmb(); | 2121 | smp_rmb(); |
2118 | 2122 | ||
2119 | /* Determine first and last group to examine based on start and len */ | 2123 | /* Determine first and last group to examine based on start and len */ |
2120 | ext3_get_group_no_and_offset(sb, (ext3_fsblk_t) start, | 2124 | ext3_get_group_no_and_offset(sb, (ext3_fsblk_t) start, |
2121 | &first_group, &first_block); | 2125 | &first_group, &first_block); |
2122 | ext3_get_group_no_and_offset(sb, (ext3_fsblk_t) (start + len), | 2126 | ext3_get_group_no_and_offset(sb, (ext3_fsblk_t) end, |
2123 | &last_group, &last_block); | 2127 | &last_group, &last_block); |
2124 | last_group = (last_group > ngroups - 1) ? ngroups - 1 : last_group; | ||
2125 | last_block = EXT3_BLOCKS_PER_GROUP(sb); | ||
2126 | 2128 | ||
2127 | if (first_group > last_group) | 2129 | /* end now represents the last block to discard in this group */ |
2128 | return -EINVAL; | 2130 | end = EXT3_BLOCKS_PER_GROUP(sb) - 1; |
2129 | 2131 | ||
2130 | for (group = first_group; group <= last_group; group++) { | 2132 | for (group = first_group; group <= last_group; group++) { |
2131 | gdp = ext3_get_group_desc(sb, group, NULL); | 2133 | gdp = ext3_get_group_desc(sb, group, NULL); |
2132 | if (!gdp) | 2134 | if (!gdp) |
2133 | break; | 2135 | break; |
2134 | 2136 | ||
2135 | free_blocks = le16_to_cpu(gdp->bg_free_blocks_count); | ||
2136 | if (free_blocks < minlen) | ||
2137 | continue; | ||
2138 | |||
2139 | /* | 2137 | /* |
2140 | * For all the groups except the last one, last block will | 2138 | * For all the groups except the last one, last block will |
2141 | * always be EXT3_BLOCKS_PER_GROUP(sb), so we only need to | 2139 | * always be EXT3_BLOCKS_PER_GROUP(sb)-1, so we only need to |
2142 | * change it for the last group in which case first_block + | 2140 | * change it for the last group, note that last_block is |
2143 | * len < EXT3_BLOCKS_PER_GROUP(sb). | 2141 | * already computed earlier by ext3_get_group_no_and_offset() |
2144 | */ | 2142 | */ |
2145 | if (first_block + len < EXT3_BLOCKS_PER_GROUP(sb)) | 2143 | if (group == last_group) |
2146 | last_block = first_block + len; | 2144 | end = last_block; |
2147 | len -= last_block - first_block; | ||
2148 | 2145 | ||
2149 | ret = ext3_trim_all_free(sb, group, first_block, | 2146 | if (le16_to_cpu(gdp->bg_free_blocks_count) >= minlen) { |
2150 | last_block, minlen); | 2147 | ret = ext3_trim_all_free(sb, group, first_block, |
2151 | if (ret < 0) | 2148 | end, minlen); |
2152 | break; | 2149 | if (ret < 0) |
2150 | break; | ||
2151 | trimmed += ret; | ||
2152 | } | ||
2153 | 2153 | ||
2154 | trimmed += ret; | 2154 | /* |
2155 | * For every group except the first one, we are sure | ||
2156 | * that the first block to discard will be block #0. | ||
2157 | */ | ||
2155 | first_block = 0; | 2158 | first_block = 0; |
2156 | } | 2159 | } |
2157 | 2160 | ||
2158 | if (ret >= 0) | 2161 | if (ret > 0) |
2159 | ret = 0; | 2162 | ret = 0; |
2160 | range->len = trimmed * sb->s_blocksize; | ||
2161 | 2163 | ||
2164 | out: | ||
2165 | range->len = trimmed * sb->s_blocksize; | ||
2162 | return ret; | 2166 | return ret; |
2163 | } | 2167 | } |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 2d0afeca0b47..6d3418662b54 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -756,6 +756,7 @@ static int ext3_splice_branch(handle_t *handle, struct inode *inode, | |||
756 | struct ext3_block_alloc_info *block_i; | 756 | struct ext3_block_alloc_info *block_i; |
757 | ext3_fsblk_t current_block; | 757 | ext3_fsblk_t current_block; |
758 | struct ext3_inode_info *ei = EXT3_I(inode); | 758 | struct ext3_inode_info *ei = EXT3_I(inode); |
759 | struct timespec now; | ||
759 | 760 | ||
760 | block_i = ei->i_block_alloc_info; | 761 | block_i = ei->i_block_alloc_info; |
761 | /* | 762 | /* |
@@ -795,9 +796,11 @@ static int ext3_splice_branch(handle_t *handle, struct inode *inode, | |||
795 | } | 796 | } |
796 | 797 | ||
797 | /* We are done with atomic stuff, now do the rest of housekeeping */ | 798 | /* We are done with atomic stuff, now do the rest of housekeeping */ |
798 | 799 | now = CURRENT_TIME_SEC; | |
799 | inode->i_ctime = CURRENT_TIME_SEC; | 800 | if (!timespec_equal(&inode->i_ctime, &now) || !where->bh) { |
800 | ext3_mark_inode_dirty(handle, inode); | 801 | inode->i_ctime = now; |
802 | ext3_mark_inode_dirty(handle, inode); | ||
803 | } | ||
801 | /* ext3_mark_inode_dirty already updated i_sync_tid */ | 804 | /* ext3_mark_inode_dirty already updated i_sync_tid */ |
802 | atomic_set(&ei->i_datasync_tid, handle->h_transaction->t_tid); | 805 | atomic_set(&ei->i_datasync_tid, handle->h_transaction->t_tid); |
803 | 806 | ||
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 8b4f12b33f57..d69a1d1d7e15 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
@@ -1110,6 +1110,13 @@ static void dquot_decr_space(struct dquot *dquot, qsize_t number) | |||
1110 | clear_bit(DQ_BLKS_B, &dquot->dq_flags); | 1110 | clear_bit(DQ_BLKS_B, &dquot->dq_flags); |
1111 | } | 1111 | } |
1112 | 1112 | ||
1113 | struct dquot_warn { | ||
1114 | struct super_block *w_sb; | ||
1115 | qid_t w_dq_id; | ||
1116 | short w_dq_type; | ||
1117 | short w_type; | ||
1118 | }; | ||
1119 | |||
1113 | static int warning_issued(struct dquot *dquot, const int warntype) | 1120 | static int warning_issued(struct dquot *dquot, const int warntype) |
1114 | { | 1121 | { |
1115 | int flag = (warntype == QUOTA_NL_BHARDWARN || | 1122 | int flag = (warntype == QUOTA_NL_BHARDWARN || |
@@ -1125,41 +1132,42 @@ static int warning_issued(struct dquot *dquot, const int warntype) | |||
1125 | #ifdef CONFIG_PRINT_QUOTA_WARNING | 1132 | #ifdef CONFIG_PRINT_QUOTA_WARNING |
1126 | static int flag_print_warnings = 1; | 1133 | static int flag_print_warnings = 1; |
1127 | 1134 | ||
1128 | static int need_print_warning(struct dquot *dquot) | 1135 | static int need_print_warning(struct dquot_warn *warn) |
1129 | { | 1136 | { |
1130 | if (!flag_print_warnings) | 1137 | if (!flag_print_warnings) |
1131 | return 0; | 1138 | return 0; |
1132 | 1139 | ||
1133 | switch (dquot->dq_type) { | 1140 | switch (warn->w_dq_type) { |
1134 | case USRQUOTA: | 1141 | case USRQUOTA: |
1135 | return current_fsuid() == dquot->dq_id; | 1142 | return current_fsuid() == warn->w_dq_id; |
1136 | case GRPQUOTA: | 1143 | case GRPQUOTA: |
1137 | return in_group_p(dquot->dq_id); | 1144 | return in_group_p(warn->w_dq_id); |
1138 | } | 1145 | } |
1139 | return 0; | 1146 | return 0; |
1140 | } | 1147 | } |
1141 | 1148 | ||
1142 | /* Print warning to user which exceeded quota */ | 1149 | /* Print warning to user which exceeded quota */ |
1143 | static void print_warning(struct dquot *dquot, const int warntype) | 1150 | static void print_warning(struct dquot_warn *warn) |
1144 | { | 1151 | { |
1145 | char *msg = NULL; | 1152 | char *msg = NULL; |
1146 | struct tty_struct *tty; | 1153 | struct tty_struct *tty; |
1154 | int warntype = warn->w_type; | ||
1147 | 1155 | ||
1148 | if (warntype == QUOTA_NL_IHARDBELOW || | 1156 | if (warntype == QUOTA_NL_IHARDBELOW || |
1149 | warntype == QUOTA_NL_ISOFTBELOW || | 1157 | warntype == QUOTA_NL_ISOFTBELOW || |
1150 | warntype == QUOTA_NL_BHARDBELOW || | 1158 | warntype == QUOTA_NL_BHARDBELOW || |
1151 | warntype == QUOTA_NL_BSOFTBELOW || !need_print_warning(dquot)) | 1159 | warntype == QUOTA_NL_BSOFTBELOW || !need_print_warning(warn)) |
1152 | return; | 1160 | return; |
1153 | 1161 | ||
1154 | tty = get_current_tty(); | 1162 | tty = get_current_tty(); |
1155 | if (!tty) | 1163 | if (!tty) |
1156 | return; | 1164 | return; |
1157 | tty_write_message(tty, dquot->dq_sb->s_id); | 1165 | tty_write_message(tty, warn->w_sb->s_id); |
1158 | if (warntype == QUOTA_NL_ISOFTWARN || warntype == QUOTA_NL_BSOFTWARN) | 1166 | if (warntype == QUOTA_NL_ISOFTWARN || warntype == QUOTA_NL_BSOFTWARN) |
1159 | tty_write_message(tty, ": warning, "); | 1167 | tty_write_message(tty, ": warning, "); |
1160 | else | 1168 | else |
1161 | tty_write_message(tty, ": write failed, "); | 1169 | tty_write_message(tty, ": write failed, "); |
1162 | tty_write_message(tty, quotatypes[dquot->dq_type]); | 1170 | tty_write_message(tty, quotatypes[warn->w_dq_type]); |
1163 | switch (warntype) { | 1171 | switch (warntype) { |
1164 | case QUOTA_NL_IHARDWARN: | 1172 | case QUOTA_NL_IHARDWARN: |
1165 | msg = " file limit reached.\r\n"; | 1173 | msg = " file limit reached.\r\n"; |
@@ -1185,26 +1193,34 @@ static void print_warning(struct dquot *dquot, const int warntype) | |||
1185 | } | 1193 | } |
1186 | #endif | 1194 | #endif |
1187 | 1195 | ||
1196 | static void prepare_warning(struct dquot_warn *warn, struct dquot *dquot, | ||
1197 | int warntype) | ||
1198 | { | ||
1199 | if (warning_issued(dquot, warntype)) | ||
1200 | return; | ||
1201 | warn->w_type = warntype; | ||
1202 | warn->w_sb = dquot->dq_sb; | ||
1203 | warn->w_dq_id = dquot->dq_id; | ||
1204 | warn->w_dq_type = dquot->dq_type; | ||
1205 | } | ||
1206 | |||
1188 | /* | 1207 | /* |
1189 | * Write warnings to the console and send warning messages over netlink. | 1208 | * Write warnings to the console and send warning messages over netlink. |
1190 | * | 1209 | * |
1191 | * Note that this function can sleep. | 1210 | * Note that this function can call into tty and networking code. |
1192 | */ | 1211 | */ |
1193 | static void flush_warnings(struct dquot *const *dquots, char *warntype) | 1212 | static void flush_warnings(struct dquot_warn *warn) |
1194 | { | 1213 | { |
1195 | struct dquot *dq; | ||
1196 | int i; | 1214 | int i; |
1197 | 1215 | ||
1198 | for (i = 0; i < MAXQUOTAS; i++) { | 1216 | for (i = 0; i < MAXQUOTAS; i++) { |
1199 | dq = dquots[i]; | 1217 | if (warn[i].w_type == QUOTA_NL_NOWARN) |
1200 | if (dq && warntype[i] != QUOTA_NL_NOWARN && | 1218 | continue; |
1201 | !warning_issued(dq, warntype[i])) { | ||
1202 | #ifdef CONFIG_PRINT_QUOTA_WARNING | 1219 | #ifdef CONFIG_PRINT_QUOTA_WARNING |
1203 | print_warning(dq, warntype[i]); | 1220 | print_warning(&warn[i]); |
1204 | #endif | 1221 | #endif |
1205 | quota_send_warning(dq->dq_type, dq->dq_id, | 1222 | quota_send_warning(warn[i].w_dq_type, warn[i].w_dq_id, |
1206 | dq->dq_sb->s_dev, warntype[i]); | 1223 | warn[i].w_sb->s_dev, warn[i].w_type); |
1207 | } | ||
1208 | } | 1224 | } |
1209 | } | 1225 | } |
1210 | 1226 | ||
@@ -1218,11 +1234,11 @@ static int ignore_hardlimit(struct dquot *dquot) | |||
1218 | } | 1234 | } |
1219 | 1235 | ||
1220 | /* needs dq_data_lock */ | 1236 | /* needs dq_data_lock */ |
1221 | static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype) | 1237 | static int check_idq(struct dquot *dquot, qsize_t inodes, |
1238 | struct dquot_warn *warn) | ||
1222 | { | 1239 | { |
1223 | qsize_t newinodes = dquot->dq_dqb.dqb_curinodes + inodes; | 1240 | qsize_t newinodes = dquot->dq_dqb.dqb_curinodes + inodes; |
1224 | 1241 | ||
1225 | *warntype = QUOTA_NL_NOWARN; | ||
1226 | if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) || | 1242 | if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) || |
1227 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) | 1243 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) |
1228 | return 0; | 1244 | return 0; |
@@ -1230,7 +1246,7 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype) | |||
1230 | if (dquot->dq_dqb.dqb_ihardlimit && | 1246 | if (dquot->dq_dqb.dqb_ihardlimit && |
1231 | newinodes > dquot->dq_dqb.dqb_ihardlimit && | 1247 | newinodes > dquot->dq_dqb.dqb_ihardlimit && |
1232 | !ignore_hardlimit(dquot)) { | 1248 | !ignore_hardlimit(dquot)) { |
1233 | *warntype = QUOTA_NL_IHARDWARN; | 1249 | prepare_warning(warn, dquot, QUOTA_NL_IHARDWARN); |
1234 | return -EDQUOT; | 1250 | return -EDQUOT; |
1235 | } | 1251 | } |
1236 | 1252 | ||
@@ -1239,14 +1255,14 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype) | |||
1239 | dquot->dq_dqb.dqb_itime && | 1255 | dquot->dq_dqb.dqb_itime && |
1240 | get_seconds() >= dquot->dq_dqb.dqb_itime && | 1256 | get_seconds() >= dquot->dq_dqb.dqb_itime && |
1241 | !ignore_hardlimit(dquot)) { | 1257 | !ignore_hardlimit(dquot)) { |
1242 | *warntype = QUOTA_NL_ISOFTLONGWARN; | 1258 | prepare_warning(warn, dquot, QUOTA_NL_ISOFTLONGWARN); |
1243 | return -EDQUOT; | 1259 | return -EDQUOT; |
1244 | } | 1260 | } |
1245 | 1261 | ||
1246 | if (dquot->dq_dqb.dqb_isoftlimit && | 1262 | if (dquot->dq_dqb.dqb_isoftlimit && |
1247 | newinodes > dquot->dq_dqb.dqb_isoftlimit && | 1263 | newinodes > dquot->dq_dqb.dqb_isoftlimit && |
1248 | dquot->dq_dqb.dqb_itime == 0) { | 1264 | dquot->dq_dqb.dqb_itime == 0) { |
1249 | *warntype = QUOTA_NL_ISOFTWARN; | 1265 | prepare_warning(warn, dquot, QUOTA_NL_ISOFTWARN); |
1250 | dquot->dq_dqb.dqb_itime = get_seconds() + | 1266 | dquot->dq_dqb.dqb_itime = get_seconds() + |
1251 | sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace; | 1267 | sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace; |
1252 | } | 1268 | } |
@@ -1255,12 +1271,12 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype) | |||
1255 | } | 1271 | } |
1256 | 1272 | ||
1257 | /* needs dq_data_lock */ | 1273 | /* needs dq_data_lock */ |
1258 | static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *warntype) | 1274 | static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, |
1275 | struct dquot_warn *warn) | ||
1259 | { | 1276 | { |
1260 | qsize_t tspace; | 1277 | qsize_t tspace; |
1261 | struct super_block *sb = dquot->dq_sb; | 1278 | struct super_block *sb = dquot->dq_sb; |
1262 | 1279 | ||
1263 | *warntype = QUOTA_NL_NOWARN; | ||
1264 | if (!sb_has_quota_limits_enabled(sb, dquot->dq_type) || | 1280 | if (!sb_has_quota_limits_enabled(sb, dquot->dq_type) || |
1265 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) | 1281 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) |
1266 | return 0; | 1282 | return 0; |
@@ -1272,7 +1288,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war | |||
1272 | tspace > dquot->dq_dqb.dqb_bhardlimit && | 1288 | tspace > dquot->dq_dqb.dqb_bhardlimit && |
1273 | !ignore_hardlimit(dquot)) { | 1289 | !ignore_hardlimit(dquot)) { |
1274 | if (!prealloc) | 1290 | if (!prealloc) |
1275 | *warntype = QUOTA_NL_BHARDWARN; | 1291 | prepare_warning(warn, dquot, QUOTA_NL_BHARDWARN); |
1276 | return -EDQUOT; | 1292 | return -EDQUOT; |
1277 | } | 1293 | } |
1278 | 1294 | ||
@@ -1282,7 +1298,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war | |||
1282 | get_seconds() >= dquot->dq_dqb.dqb_btime && | 1298 | get_seconds() >= dquot->dq_dqb.dqb_btime && |
1283 | !ignore_hardlimit(dquot)) { | 1299 | !ignore_hardlimit(dquot)) { |
1284 | if (!prealloc) | 1300 | if (!prealloc) |
1285 | *warntype = QUOTA_NL_BSOFTLONGWARN; | 1301 | prepare_warning(warn, dquot, QUOTA_NL_BSOFTLONGWARN); |
1286 | return -EDQUOT; | 1302 | return -EDQUOT; |
1287 | } | 1303 | } |
1288 | 1304 | ||
@@ -1290,7 +1306,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war | |||
1290 | tspace > dquot->dq_dqb.dqb_bsoftlimit && | 1306 | tspace > dquot->dq_dqb.dqb_bsoftlimit && |
1291 | dquot->dq_dqb.dqb_btime == 0) { | 1307 | dquot->dq_dqb.dqb_btime == 0) { |
1292 | if (!prealloc) { | 1308 | if (!prealloc) { |
1293 | *warntype = QUOTA_NL_BSOFTWARN; | 1309 | prepare_warning(warn, dquot, QUOTA_NL_BSOFTWARN); |
1294 | dquot->dq_dqb.dqb_btime = get_seconds() + | 1310 | dquot->dq_dqb.dqb_btime = get_seconds() + |
1295 | sb_dqopt(sb)->info[dquot->dq_type].dqi_bgrace; | 1311 | sb_dqopt(sb)->info[dquot->dq_type].dqi_bgrace; |
1296 | } | 1312 | } |
@@ -1543,10 +1559,9 @@ static void inode_decr_space(struct inode *inode, qsize_t number, int reserve) | |||
1543 | int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) | 1559 | int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) |
1544 | { | 1560 | { |
1545 | int cnt, ret = 0; | 1561 | int cnt, ret = 0; |
1546 | char warntype[MAXQUOTAS]; | 1562 | struct dquot_warn warn[MAXQUOTAS]; |
1547 | int warn = flags & DQUOT_SPACE_WARN; | 1563 | struct dquot **dquots = inode->i_dquot; |
1548 | int reserve = flags & DQUOT_SPACE_RESERVE; | 1564 | int reserve = flags & DQUOT_SPACE_RESERVE; |
1549 | int nofail = flags & DQUOT_SPACE_NOFAIL; | ||
1550 | 1565 | ||
1551 | /* | 1566 | /* |
1552 | * First test before acquiring mutex - solves deadlocks when we | 1567 | * First test before acquiring mutex - solves deadlocks when we |
@@ -1559,36 +1574,36 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) | |||
1559 | 1574 | ||
1560 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1575 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1561 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | 1576 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) |
1562 | warntype[cnt] = QUOTA_NL_NOWARN; | 1577 | warn[cnt].w_type = QUOTA_NL_NOWARN; |
1563 | 1578 | ||
1564 | spin_lock(&dq_data_lock); | 1579 | spin_lock(&dq_data_lock); |
1565 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1580 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1566 | if (!inode->i_dquot[cnt]) | 1581 | if (!dquots[cnt]) |
1567 | continue; | 1582 | continue; |
1568 | ret = check_bdq(inode->i_dquot[cnt], number, !warn, | 1583 | ret = check_bdq(dquots[cnt], number, |
1569 | warntype+cnt); | 1584 | !(flags & DQUOT_SPACE_WARN), &warn[cnt]); |
1570 | if (ret && !nofail) { | 1585 | if (ret && !(flags & DQUOT_SPACE_NOFAIL)) { |
1571 | spin_unlock(&dq_data_lock); | 1586 | spin_unlock(&dq_data_lock); |
1572 | goto out_flush_warn; | 1587 | goto out_flush_warn; |
1573 | } | 1588 | } |
1574 | } | 1589 | } |
1575 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1590 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1576 | if (!inode->i_dquot[cnt]) | 1591 | if (!dquots[cnt]) |
1577 | continue; | 1592 | continue; |
1578 | if (reserve) | 1593 | if (reserve) |
1579 | dquot_resv_space(inode->i_dquot[cnt], number); | 1594 | dquot_resv_space(dquots[cnt], number); |
1580 | else | 1595 | else |
1581 | dquot_incr_space(inode->i_dquot[cnt], number); | 1596 | dquot_incr_space(dquots[cnt], number); |
1582 | } | 1597 | } |
1583 | inode_incr_space(inode, number, reserve); | 1598 | inode_incr_space(inode, number, reserve); |
1584 | spin_unlock(&dq_data_lock); | 1599 | spin_unlock(&dq_data_lock); |
1585 | 1600 | ||
1586 | if (reserve) | 1601 | if (reserve) |
1587 | goto out_flush_warn; | 1602 | goto out_flush_warn; |
1588 | mark_all_dquot_dirty(inode->i_dquot); | 1603 | mark_all_dquot_dirty(dquots); |
1589 | out_flush_warn: | 1604 | out_flush_warn: |
1590 | flush_warnings(inode->i_dquot, warntype); | ||
1591 | up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1605 | up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1606 | flush_warnings(warn); | ||
1592 | out: | 1607 | out: |
1593 | return ret; | 1608 | return ret; |
1594 | } | 1609 | } |
@@ -1600,36 +1615,37 @@ EXPORT_SYMBOL(__dquot_alloc_space); | |||
1600 | int dquot_alloc_inode(const struct inode *inode) | 1615 | int dquot_alloc_inode(const struct inode *inode) |
1601 | { | 1616 | { |
1602 | int cnt, ret = 0; | 1617 | int cnt, ret = 0; |
1603 | char warntype[MAXQUOTAS]; | 1618 | struct dquot_warn warn[MAXQUOTAS]; |
1619 | struct dquot * const *dquots = inode->i_dquot; | ||
1604 | 1620 | ||
1605 | /* First test before acquiring mutex - solves deadlocks when we | 1621 | /* First test before acquiring mutex - solves deadlocks when we |
1606 | * re-enter the quota code and are already holding the mutex */ | 1622 | * re-enter the quota code and are already holding the mutex */ |
1607 | if (!dquot_active(inode)) | 1623 | if (!dquot_active(inode)) |
1608 | return 0; | 1624 | return 0; |
1609 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | 1625 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) |
1610 | warntype[cnt] = QUOTA_NL_NOWARN; | 1626 | warn[cnt].w_type = QUOTA_NL_NOWARN; |
1611 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1627 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1612 | spin_lock(&dq_data_lock); | 1628 | spin_lock(&dq_data_lock); |
1613 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1629 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1614 | if (!inode->i_dquot[cnt]) | 1630 | if (!dquots[cnt]) |
1615 | continue; | 1631 | continue; |
1616 | ret = check_idq(inode->i_dquot[cnt], 1, warntype + cnt); | 1632 | ret = check_idq(dquots[cnt], 1, &warn[cnt]); |
1617 | if (ret) | 1633 | if (ret) |
1618 | goto warn_put_all; | 1634 | goto warn_put_all; |
1619 | } | 1635 | } |
1620 | 1636 | ||
1621 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1637 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1622 | if (!inode->i_dquot[cnt]) | 1638 | if (!dquots[cnt]) |
1623 | continue; | 1639 | continue; |
1624 | dquot_incr_inodes(inode->i_dquot[cnt], 1); | 1640 | dquot_incr_inodes(dquots[cnt], 1); |
1625 | } | 1641 | } |
1626 | 1642 | ||
1627 | warn_put_all: | 1643 | warn_put_all: |
1628 | spin_unlock(&dq_data_lock); | 1644 | spin_unlock(&dq_data_lock); |
1629 | if (ret == 0) | 1645 | if (ret == 0) |
1630 | mark_all_dquot_dirty(inode->i_dquot); | 1646 | mark_all_dquot_dirty(dquots); |
1631 | flush_warnings(inode->i_dquot, warntype); | ||
1632 | up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1647 | up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1648 | flush_warnings(warn); | ||
1633 | return ret; | 1649 | return ret; |
1634 | } | 1650 | } |
1635 | EXPORT_SYMBOL(dquot_alloc_inode); | 1651 | EXPORT_SYMBOL(dquot_alloc_inode); |
@@ -1669,7 +1685,8 @@ EXPORT_SYMBOL(dquot_claim_space_nodirty); | |||
1669 | void __dquot_free_space(struct inode *inode, qsize_t number, int flags) | 1685 | void __dquot_free_space(struct inode *inode, qsize_t number, int flags) |
1670 | { | 1686 | { |
1671 | unsigned int cnt; | 1687 | unsigned int cnt; |
1672 | char warntype[MAXQUOTAS]; | 1688 | struct dquot_warn warn[MAXQUOTAS]; |
1689 | struct dquot **dquots = inode->i_dquot; | ||
1673 | int reserve = flags & DQUOT_SPACE_RESERVE; | 1690 | int reserve = flags & DQUOT_SPACE_RESERVE; |
1674 | 1691 | ||
1675 | /* First test before acquiring mutex - solves deadlocks when we | 1692 | /* First test before acquiring mutex - solves deadlocks when we |
@@ -1682,23 +1699,28 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags) | |||
1682 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1699 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1683 | spin_lock(&dq_data_lock); | 1700 | spin_lock(&dq_data_lock); |
1684 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1701 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1685 | if (!inode->i_dquot[cnt]) | 1702 | int wtype; |
1703 | |||
1704 | warn[cnt].w_type = QUOTA_NL_NOWARN; | ||
1705 | if (!dquots[cnt]) | ||
1686 | continue; | 1706 | continue; |
1687 | warntype[cnt] = info_bdq_free(inode->i_dquot[cnt], number); | 1707 | wtype = info_bdq_free(dquots[cnt], number); |
1708 | if (wtype != QUOTA_NL_NOWARN) | ||
1709 | prepare_warning(&warn[cnt], dquots[cnt], wtype); | ||
1688 | if (reserve) | 1710 | if (reserve) |
1689 | dquot_free_reserved_space(inode->i_dquot[cnt], number); | 1711 | dquot_free_reserved_space(dquots[cnt], number); |
1690 | else | 1712 | else |
1691 | dquot_decr_space(inode->i_dquot[cnt], number); | 1713 | dquot_decr_space(dquots[cnt], number); |
1692 | } | 1714 | } |
1693 | inode_decr_space(inode, number, reserve); | 1715 | inode_decr_space(inode, number, reserve); |
1694 | spin_unlock(&dq_data_lock); | 1716 | spin_unlock(&dq_data_lock); |
1695 | 1717 | ||
1696 | if (reserve) | 1718 | if (reserve) |
1697 | goto out_unlock; | 1719 | goto out_unlock; |
1698 | mark_all_dquot_dirty(inode->i_dquot); | 1720 | mark_all_dquot_dirty(dquots); |
1699 | out_unlock: | 1721 | out_unlock: |
1700 | flush_warnings(inode->i_dquot, warntype); | ||
1701 | up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1722 | up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1723 | flush_warnings(warn); | ||
1702 | } | 1724 | } |
1703 | EXPORT_SYMBOL(__dquot_free_space); | 1725 | EXPORT_SYMBOL(__dquot_free_space); |
1704 | 1726 | ||
@@ -1708,7 +1730,8 @@ EXPORT_SYMBOL(__dquot_free_space); | |||
1708 | void dquot_free_inode(const struct inode *inode) | 1730 | void dquot_free_inode(const struct inode *inode) |
1709 | { | 1731 | { |
1710 | unsigned int cnt; | 1732 | unsigned int cnt; |
1711 | char warntype[MAXQUOTAS]; | 1733 | struct dquot_warn warn[MAXQUOTAS]; |
1734 | struct dquot * const *dquots = inode->i_dquot; | ||
1712 | 1735 | ||
1713 | /* First test before acquiring mutex - solves deadlocks when we | 1736 | /* First test before acquiring mutex - solves deadlocks when we |
1714 | * re-enter the quota code and are already holding the mutex */ | 1737 | * re-enter the quota code and are already holding the mutex */ |
@@ -1718,15 +1741,20 @@ void dquot_free_inode(const struct inode *inode) | |||
1718 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1741 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1719 | spin_lock(&dq_data_lock); | 1742 | spin_lock(&dq_data_lock); |
1720 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1743 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1721 | if (!inode->i_dquot[cnt]) | 1744 | int wtype; |
1745 | |||
1746 | warn[cnt].w_type = QUOTA_NL_NOWARN; | ||
1747 | if (!dquots[cnt]) | ||
1722 | continue; | 1748 | continue; |
1723 | warntype[cnt] = info_idq_free(inode->i_dquot[cnt], 1); | 1749 | wtype = info_idq_free(dquots[cnt], 1); |
1724 | dquot_decr_inodes(inode->i_dquot[cnt], 1); | 1750 | if (wtype != QUOTA_NL_NOWARN) |
1751 | prepare_warning(&warn[cnt], dquots[cnt], wtype); | ||
1752 | dquot_decr_inodes(dquots[cnt], 1); | ||
1725 | } | 1753 | } |
1726 | spin_unlock(&dq_data_lock); | 1754 | spin_unlock(&dq_data_lock); |
1727 | mark_all_dquot_dirty(inode->i_dquot); | 1755 | mark_all_dquot_dirty(dquots); |
1728 | flush_warnings(inode->i_dquot, warntype); | ||
1729 | up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1756 | up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1757 | flush_warnings(warn); | ||
1730 | } | 1758 | } |
1731 | EXPORT_SYMBOL(dquot_free_inode); | 1759 | EXPORT_SYMBOL(dquot_free_inode); |
1732 | 1760 | ||
@@ -1747,16 +1775,20 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) | |||
1747 | struct dquot *transfer_from[MAXQUOTAS] = {}; | 1775 | struct dquot *transfer_from[MAXQUOTAS] = {}; |
1748 | int cnt, ret = 0; | 1776 | int cnt, ret = 0; |
1749 | char is_valid[MAXQUOTAS] = {}; | 1777 | char is_valid[MAXQUOTAS] = {}; |
1750 | char warntype_to[MAXQUOTAS]; | 1778 | struct dquot_warn warn_to[MAXQUOTAS]; |
1751 | char warntype_from_inodes[MAXQUOTAS], warntype_from_space[MAXQUOTAS]; | 1779 | struct dquot_warn warn_from_inodes[MAXQUOTAS]; |
1780 | struct dquot_warn warn_from_space[MAXQUOTAS]; | ||
1752 | 1781 | ||
1753 | /* First test before acquiring mutex - solves deadlocks when we | 1782 | /* First test before acquiring mutex - solves deadlocks when we |
1754 | * re-enter the quota code and are already holding the mutex */ | 1783 | * re-enter the quota code and are already holding the mutex */ |
1755 | if (IS_NOQUOTA(inode)) | 1784 | if (IS_NOQUOTA(inode)) |
1756 | return 0; | 1785 | return 0; |
1757 | /* Initialize the arrays */ | 1786 | /* Initialize the arrays */ |
1758 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | 1787 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1759 | warntype_to[cnt] = QUOTA_NL_NOWARN; | 1788 | warn_to[cnt].w_type = QUOTA_NL_NOWARN; |
1789 | warn_from_inodes[cnt].w_type = QUOTA_NL_NOWARN; | ||
1790 | warn_from_space[cnt].w_type = QUOTA_NL_NOWARN; | ||
1791 | } | ||
1760 | down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1792 | down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1761 | if (IS_NOQUOTA(inode)) { /* File without quota accounting? */ | 1793 | if (IS_NOQUOTA(inode)) { /* File without quota accounting? */ |
1762 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1794 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); |
@@ -1778,10 +1810,10 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) | |||
1778 | continue; | 1810 | continue; |
1779 | is_valid[cnt] = 1; | 1811 | is_valid[cnt] = 1; |
1780 | transfer_from[cnt] = inode->i_dquot[cnt]; | 1812 | transfer_from[cnt] = inode->i_dquot[cnt]; |
1781 | ret = check_idq(transfer_to[cnt], 1, warntype_to + cnt); | 1813 | ret = check_idq(transfer_to[cnt], 1, &warn_to[cnt]); |
1782 | if (ret) | 1814 | if (ret) |
1783 | goto over_quota; | 1815 | goto over_quota; |
1784 | ret = check_bdq(transfer_to[cnt], space, 0, warntype_to + cnt); | 1816 | ret = check_bdq(transfer_to[cnt], space, 0, &warn_to[cnt]); |
1785 | if (ret) | 1817 | if (ret) |
1786 | goto over_quota; | 1818 | goto over_quota; |
1787 | } | 1819 | } |
@@ -1794,10 +1826,15 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) | |||
1794 | continue; | 1826 | continue; |
1795 | /* Due to IO error we might not have transfer_from[] structure */ | 1827 | /* Due to IO error we might not have transfer_from[] structure */ |
1796 | if (transfer_from[cnt]) { | 1828 | if (transfer_from[cnt]) { |
1797 | warntype_from_inodes[cnt] = | 1829 | int wtype; |
1798 | info_idq_free(transfer_from[cnt], 1); | 1830 | wtype = info_idq_free(transfer_from[cnt], 1); |
1799 | warntype_from_space[cnt] = | 1831 | if (wtype != QUOTA_NL_NOWARN) |
1800 | info_bdq_free(transfer_from[cnt], space); | 1832 | prepare_warning(&warn_from_inodes[cnt], |
1833 | transfer_from[cnt], wtype); | ||
1834 | wtype = info_bdq_free(transfer_from[cnt], space); | ||
1835 | if (wtype != QUOTA_NL_NOWARN) | ||
1836 | prepare_warning(&warn_from_space[cnt], | ||
1837 | transfer_from[cnt], wtype); | ||
1801 | dquot_decr_inodes(transfer_from[cnt], 1); | 1838 | dquot_decr_inodes(transfer_from[cnt], 1); |
1802 | dquot_decr_space(transfer_from[cnt], cur_space); | 1839 | dquot_decr_space(transfer_from[cnt], cur_space); |
1803 | dquot_free_reserved_space(transfer_from[cnt], | 1840 | dquot_free_reserved_space(transfer_from[cnt], |
@@ -1815,9 +1852,9 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) | |||
1815 | 1852 | ||
1816 | mark_all_dquot_dirty(transfer_from); | 1853 | mark_all_dquot_dirty(transfer_from); |
1817 | mark_all_dquot_dirty(transfer_to); | 1854 | mark_all_dquot_dirty(transfer_to); |
1818 | flush_warnings(transfer_to, warntype_to); | 1855 | flush_warnings(warn_to); |
1819 | flush_warnings(transfer_from, warntype_from_inodes); | 1856 | flush_warnings(warn_from_inodes); |
1820 | flush_warnings(transfer_from, warntype_from_space); | 1857 | flush_warnings(warn_from_space); |
1821 | /* Pass back references to put */ | 1858 | /* Pass back references to put */ |
1822 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | 1859 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) |
1823 | if (is_valid[cnt]) | 1860 | if (is_valid[cnt]) |
@@ -1826,7 +1863,7 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) | |||
1826 | over_quota: | 1863 | over_quota: |
1827 | spin_unlock(&dq_data_lock); | 1864 | spin_unlock(&dq_data_lock); |
1828 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1865 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1829 | flush_warnings(transfer_to, warntype_to); | 1866 | flush_warnings(warn_to); |
1830 | return ret; | 1867 | return ret; |
1831 | } | 1868 | } |
1832 | EXPORT_SYMBOL(__dquot_transfer); | 1869 | EXPORT_SYMBOL(__dquot_transfer); |
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c index 987585bb0a1d..1ba2baaf4367 100644 --- a/fs/udf/balloc.c +++ b/fs/udf/balloc.c | |||
@@ -105,7 +105,6 @@ static void udf_add_free_space(struct super_block *sb, u16 partition, u32 cnt) | |||
105 | } | 105 | } |
106 | 106 | ||
107 | static void udf_bitmap_free_blocks(struct super_block *sb, | 107 | static void udf_bitmap_free_blocks(struct super_block *sb, |
108 | struct inode *inode, | ||
109 | struct udf_bitmap *bitmap, | 108 | struct udf_bitmap *bitmap, |
110 | struct kernel_lb_addr *bloc, | 109 | struct kernel_lb_addr *bloc, |
111 | uint32_t offset, | 110 | uint32_t offset, |
@@ -172,7 +171,6 @@ error_return: | |||
172 | } | 171 | } |
173 | 172 | ||
174 | static int udf_bitmap_prealloc_blocks(struct super_block *sb, | 173 | static int udf_bitmap_prealloc_blocks(struct super_block *sb, |
175 | struct inode *inode, | ||
176 | struct udf_bitmap *bitmap, | 174 | struct udf_bitmap *bitmap, |
177 | uint16_t partition, uint32_t first_block, | 175 | uint16_t partition, uint32_t first_block, |
178 | uint32_t block_count) | 176 | uint32_t block_count) |
@@ -223,7 +221,6 @@ out: | |||
223 | } | 221 | } |
224 | 222 | ||
225 | static int udf_bitmap_new_block(struct super_block *sb, | 223 | static int udf_bitmap_new_block(struct super_block *sb, |
226 | struct inode *inode, | ||
227 | struct udf_bitmap *bitmap, uint16_t partition, | 224 | struct udf_bitmap *bitmap, uint16_t partition, |
228 | uint32_t goal, int *err) | 225 | uint32_t goal, int *err) |
229 | { | 226 | { |
@@ -349,7 +346,6 @@ error_return: | |||
349 | } | 346 | } |
350 | 347 | ||
351 | static void udf_table_free_blocks(struct super_block *sb, | 348 | static void udf_table_free_blocks(struct super_block *sb, |
352 | struct inode *inode, | ||
353 | struct inode *table, | 349 | struct inode *table, |
354 | struct kernel_lb_addr *bloc, | 350 | struct kernel_lb_addr *bloc, |
355 | uint32_t offset, | 351 | uint32_t offset, |
@@ -581,7 +577,6 @@ error_return: | |||
581 | } | 577 | } |
582 | 578 | ||
583 | static int udf_table_prealloc_blocks(struct super_block *sb, | 579 | static int udf_table_prealloc_blocks(struct super_block *sb, |
584 | struct inode *inode, | ||
585 | struct inode *table, uint16_t partition, | 580 | struct inode *table, uint16_t partition, |
586 | uint32_t first_block, uint32_t block_count) | 581 | uint32_t first_block, uint32_t block_count) |
587 | { | 582 | { |
@@ -643,7 +638,6 @@ static int udf_table_prealloc_blocks(struct super_block *sb, | |||
643 | } | 638 | } |
644 | 639 | ||
645 | static int udf_table_new_block(struct super_block *sb, | 640 | static int udf_table_new_block(struct super_block *sb, |
646 | struct inode *inode, | ||
647 | struct inode *table, uint16_t partition, | 641 | struct inode *table, uint16_t partition, |
648 | uint32_t goal, int *err) | 642 | uint32_t goal, int *err) |
649 | { | 643 | { |
@@ -743,18 +737,23 @@ void udf_free_blocks(struct super_block *sb, struct inode *inode, | |||
743 | struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; | 737 | struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; |
744 | 738 | ||
745 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) { | 739 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) { |
746 | udf_bitmap_free_blocks(sb, inode, map->s_uspace.s_bitmap, | 740 | udf_bitmap_free_blocks(sb, map->s_uspace.s_bitmap, |
747 | bloc, offset, count); | 741 | bloc, offset, count); |
748 | } else if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) { | 742 | } else if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) { |
749 | udf_table_free_blocks(sb, inode, map->s_uspace.s_table, | 743 | udf_table_free_blocks(sb, map->s_uspace.s_table, |
750 | bloc, offset, count); | 744 | bloc, offset, count); |
751 | } else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) { | 745 | } else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) { |
752 | udf_bitmap_free_blocks(sb, inode, map->s_fspace.s_bitmap, | 746 | udf_bitmap_free_blocks(sb, map->s_fspace.s_bitmap, |
753 | bloc, offset, count); | 747 | bloc, offset, count); |
754 | } else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) { | 748 | } else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) { |
755 | udf_table_free_blocks(sb, inode, map->s_fspace.s_table, | 749 | udf_table_free_blocks(sb, map->s_fspace.s_table, |
756 | bloc, offset, count); | 750 | bloc, offset, count); |
757 | } | 751 | } |
752 | |||
753 | if (inode) { | ||
754 | inode_sub_bytes(inode, | ||
755 | ((sector_t)count) << sb->s_blocksize_bits); | ||
756 | } | ||
758 | } | 757 | } |
759 | 758 | ||
760 | inline int udf_prealloc_blocks(struct super_block *sb, | 759 | inline int udf_prealloc_blocks(struct super_block *sb, |
@@ -763,29 +762,34 @@ inline int udf_prealloc_blocks(struct super_block *sb, | |||
763 | uint32_t block_count) | 762 | uint32_t block_count) |
764 | { | 763 | { |
765 | struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; | 764 | struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; |
765 | sector_t allocated; | ||
766 | 766 | ||
767 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) | 767 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) |
768 | return udf_bitmap_prealloc_blocks(sb, inode, | 768 | allocated = udf_bitmap_prealloc_blocks(sb, |
769 | map->s_uspace.s_bitmap, | 769 | map->s_uspace.s_bitmap, |
770 | partition, first_block, | 770 | partition, first_block, |
771 | block_count); | 771 | block_count); |
772 | else if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) | 772 | else if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) |
773 | return udf_table_prealloc_blocks(sb, inode, | 773 | allocated = udf_table_prealloc_blocks(sb, |
774 | map->s_uspace.s_table, | 774 | map->s_uspace.s_table, |
775 | partition, first_block, | 775 | partition, first_block, |
776 | block_count); | 776 | block_count); |
777 | else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) | 777 | else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) |
778 | return udf_bitmap_prealloc_blocks(sb, inode, | 778 | allocated = udf_bitmap_prealloc_blocks(sb, |
779 | map->s_fspace.s_bitmap, | 779 | map->s_fspace.s_bitmap, |
780 | partition, first_block, | 780 | partition, first_block, |
781 | block_count); | 781 | block_count); |
782 | else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) | 782 | else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) |
783 | return udf_table_prealloc_blocks(sb, inode, | 783 | allocated = udf_table_prealloc_blocks(sb, |
784 | map->s_fspace.s_table, | 784 | map->s_fspace.s_table, |
785 | partition, first_block, | 785 | partition, first_block, |
786 | block_count); | 786 | block_count); |
787 | else | 787 | else |
788 | return 0; | 788 | return 0; |
789 | |||
790 | if (inode && allocated > 0) | ||
791 | inode_add_bytes(inode, allocated << sb->s_blocksize_bits); | ||
792 | return allocated; | ||
789 | } | 793 | } |
790 | 794 | ||
791 | inline int udf_new_block(struct super_block *sb, | 795 | inline int udf_new_block(struct super_block *sb, |
@@ -793,25 +797,29 @@ inline int udf_new_block(struct super_block *sb, | |||
793 | uint16_t partition, uint32_t goal, int *err) | 797 | uint16_t partition, uint32_t goal, int *err) |
794 | { | 798 | { |
795 | struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; | 799 | struct udf_part_map *map = &UDF_SB(sb)->s_partmaps[partition]; |
800 | int block; | ||
796 | 801 | ||
797 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) | 802 | if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_BITMAP) |
798 | return udf_bitmap_new_block(sb, inode, | 803 | block = udf_bitmap_new_block(sb, |
799 | map->s_uspace.s_bitmap, | 804 | map->s_uspace.s_bitmap, |
800 | partition, goal, err); | 805 | partition, goal, err); |
801 | else if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) | 806 | else if (map->s_partition_flags & UDF_PART_FLAG_UNALLOC_TABLE) |
802 | return udf_table_new_block(sb, inode, | 807 | block = udf_table_new_block(sb, |
803 | map->s_uspace.s_table, | 808 | map->s_uspace.s_table, |
804 | partition, goal, err); | ||
805 | else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) | ||
806 | return udf_bitmap_new_block(sb, inode, | ||
807 | map->s_fspace.s_bitmap, | ||
808 | partition, goal, err); | 809 | partition, goal, err); |
810 | else if (map->s_partition_flags & UDF_PART_FLAG_FREED_BITMAP) | ||
811 | block = udf_bitmap_new_block(sb, | ||
812 | map->s_fspace.s_bitmap, | ||
813 | partition, goal, err); | ||
809 | else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) | 814 | else if (map->s_partition_flags & UDF_PART_FLAG_FREED_TABLE) |
810 | return udf_table_new_block(sb, inode, | 815 | block = udf_table_new_block(sb, |
811 | map->s_fspace.s_table, | 816 | map->s_fspace.s_table, |
812 | partition, goal, err); | 817 | partition, goal, err); |
813 | else { | 818 | else { |
814 | *err = -EIO; | 819 | *err = -EIO; |
815 | return 0; | 820 | return 0; |
816 | } | 821 | } |
822 | if (inode && block) | ||
823 | inode_add_bytes(inode, sb->s_blocksize); | ||
824 | return block; | ||
817 | } | 825 | } |
diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c index 05ab48195be9..7e5aae4bf46f 100644 --- a/fs/udf/ialloc.c +++ b/fs/udf/ialloc.c | |||
@@ -116,6 +116,7 @@ struct inode *udf_new_inode(struct inode *dir, umode_t mode, int *err) | |||
116 | iinfo->i_lenEAttr = 0; | 116 | iinfo->i_lenEAttr = 0; |
117 | iinfo->i_lenAlloc = 0; | 117 | iinfo->i_lenAlloc = 0; |
118 | iinfo->i_use = 0; | 118 | iinfo->i_use = 0; |
119 | iinfo->i_checkpoint = 1; | ||
119 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_AD_IN_ICB)) | 120 | if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_AD_IN_ICB)) |
120 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB; | 121 | iinfo->i_alloc_type = ICBTAG_FLAG_AD_IN_ICB; |
121 | else if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) | 122 | else if (UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_USE_SHORT_AD)) |
diff --git a/fs/udf/inode.c b/fs/udf/inode.c index 7699df7b3198..7d7528008359 100644 --- a/fs/udf/inode.c +++ b/fs/udf/inode.c | |||
@@ -1358,6 +1358,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
1358 | iinfo->i_unique = le64_to_cpu(fe->uniqueID); | 1358 | iinfo->i_unique = le64_to_cpu(fe->uniqueID); |
1359 | iinfo->i_lenEAttr = le32_to_cpu(fe->lengthExtendedAttr); | 1359 | iinfo->i_lenEAttr = le32_to_cpu(fe->lengthExtendedAttr); |
1360 | iinfo->i_lenAlloc = le32_to_cpu(fe->lengthAllocDescs); | 1360 | iinfo->i_lenAlloc = le32_to_cpu(fe->lengthAllocDescs); |
1361 | iinfo->i_checkpoint = le32_to_cpu(fe->checkpoint); | ||
1361 | offset = sizeof(struct fileEntry) + iinfo->i_lenEAttr; | 1362 | offset = sizeof(struct fileEntry) + iinfo->i_lenEAttr; |
1362 | } else { | 1363 | } else { |
1363 | inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) << | 1364 | inode->i_blocks = le64_to_cpu(efe->logicalBlocksRecorded) << |
@@ -1379,6 +1380,7 @@ static void udf_fill_inode(struct inode *inode, struct buffer_head *bh) | |||
1379 | iinfo->i_unique = le64_to_cpu(efe->uniqueID); | 1380 | iinfo->i_unique = le64_to_cpu(efe->uniqueID); |
1380 | iinfo->i_lenEAttr = le32_to_cpu(efe->lengthExtendedAttr); | 1381 | iinfo->i_lenEAttr = le32_to_cpu(efe->lengthExtendedAttr); |
1381 | iinfo->i_lenAlloc = le32_to_cpu(efe->lengthAllocDescs); | 1382 | iinfo->i_lenAlloc = le32_to_cpu(efe->lengthAllocDescs); |
1383 | iinfo->i_checkpoint = le32_to_cpu(efe->checkpoint); | ||
1382 | offset = sizeof(struct extendedFileEntry) + | 1384 | offset = sizeof(struct extendedFileEntry) + |
1383 | iinfo->i_lenEAttr; | 1385 | iinfo->i_lenEAttr; |
1384 | } | 1386 | } |
@@ -1495,6 +1497,7 @@ static int udf_update_inode(struct inode *inode, int do_sync) | |||
1495 | struct buffer_head *bh = NULL; | 1497 | struct buffer_head *bh = NULL; |
1496 | struct fileEntry *fe; | 1498 | struct fileEntry *fe; |
1497 | struct extendedFileEntry *efe; | 1499 | struct extendedFileEntry *efe; |
1500 | uint64_t lb_recorded; | ||
1498 | uint32_t udfperms; | 1501 | uint32_t udfperms; |
1499 | uint16_t icbflags; | 1502 | uint16_t icbflags; |
1500 | uint16_t crclen; | 1503 | uint16_t crclen; |
@@ -1589,13 +1592,18 @@ static int udf_update_inode(struct inode *inode, int do_sync) | |||
1589 | dsea->minorDeviceIdent = cpu_to_le32(iminor(inode)); | 1592 | dsea->minorDeviceIdent = cpu_to_le32(iminor(inode)); |
1590 | } | 1593 | } |
1591 | 1594 | ||
1595 | if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) | ||
1596 | lb_recorded = 0; /* No extents => no blocks! */ | ||
1597 | else | ||
1598 | lb_recorded = | ||
1599 | (inode->i_blocks + (1 << (blocksize_bits - 9)) - 1) >> | ||
1600 | (blocksize_bits - 9); | ||
1601 | |||
1592 | if (iinfo->i_efe == 0) { | 1602 | if (iinfo->i_efe == 0) { |
1593 | memcpy(bh->b_data + sizeof(struct fileEntry), | 1603 | memcpy(bh->b_data + sizeof(struct fileEntry), |
1594 | iinfo->i_ext.i_data, | 1604 | iinfo->i_ext.i_data, |
1595 | inode->i_sb->s_blocksize - sizeof(struct fileEntry)); | 1605 | inode->i_sb->s_blocksize - sizeof(struct fileEntry)); |
1596 | fe->logicalBlocksRecorded = cpu_to_le64( | 1606 | fe->logicalBlocksRecorded = cpu_to_le64(lb_recorded); |
1597 | (inode->i_blocks + (1 << (blocksize_bits - 9)) - 1) >> | ||
1598 | (blocksize_bits - 9)); | ||
1599 | 1607 | ||
1600 | udf_time_to_disk_stamp(&fe->accessTime, inode->i_atime); | 1608 | udf_time_to_disk_stamp(&fe->accessTime, inode->i_atime); |
1601 | udf_time_to_disk_stamp(&fe->modificationTime, inode->i_mtime); | 1609 | udf_time_to_disk_stamp(&fe->modificationTime, inode->i_mtime); |
@@ -1607,6 +1615,7 @@ static int udf_update_inode(struct inode *inode, int do_sync) | |||
1607 | fe->uniqueID = cpu_to_le64(iinfo->i_unique); | 1615 | fe->uniqueID = cpu_to_le64(iinfo->i_unique); |
1608 | fe->lengthExtendedAttr = cpu_to_le32(iinfo->i_lenEAttr); | 1616 | fe->lengthExtendedAttr = cpu_to_le32(iinfo->i_lenEAttr); |
1609 | fe->lengthAllocDescs = cpu_to_le32(iinfo->i_lenAlloc); | 1617 | fe->lengthAllocDescs = cpu_to_le32(iinfo->i_lenAlloc); |
1618 | fe->checkpoint = cpu_to_le32(iinfo->i_checkpoint); | ||
1610 | fe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_FE); | 1619 | fe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_FE); |
1611 | crclen = sizeof(struct fileEntry); | 1620 | crclen = sizeof(struct fileEntry); |
1612 | } else { | 1621 | } else { |
@@ -1615,9 +1624,7 @@ static int udf_update_inode(struct inode *inode, int do_sync) | |||
1615 | inode->i_sb->s_blocksize - | 1624 | inode->i_sb->s_blocksize - |
1616 | sizeof(struct extendedFileEntry)); | 1625 | sizeof(struct extendedFileEntry)); |
1617 | efe->objectSize = cpu_to_le64(inode->i_size); | 1626 | efe->objectSize = cpu_to_le64(inode->i_size); |
1618 | efe->logicalBlocksRecorded = cpu_to_le64( | 1627 | efe->logicalBlocksRecorded = cpu_to_le64(lb_recorded); |
1619 | (inode->i_blocks + (1 << (blocksize_bits - 9)) - 1) >> | ||
1620 | (blocksize_bits - 9)); | ||
1621 | 1628 | ||
1622 | if (iinfo->i_crtime.tv_sec > inode->i_atime.tv_sec || | 1629 | if (iinfo->i_crtime.tv_sec > inode->i_atime.tv_sec || |
1623 | (iinfo->i_crtime.tv_sec == inode->i_atime.tv_sec && | 1630 | (iinfo->i_crtime.tv_sec == inode->i_atime.tv_sec && |
@@ -1646,6 +1653,7 @@ static int udf_update_inode(struct inode *inode, int do_sync) | |||
1646 | efe->uniqueID = cpu_to_le64(iinfo->i_unique); | 1653 | efe->uniqueID = cpu_to_le64(iinfo->i_unique); |
1647 | efe->lengthExtendedAttr = cpu_to_le32(iinfo->i_lenEAttr); | 1654 | efe->lengthExtendedAttr = cpu_to_le32(iinfo->i_lenEAttr); |
1648 | efe->lengthAllocDescs = cpu_to_le32(iinfo->i_lenAlloc); | 1655 | efe->lengthAllocDescs = cpu_to_le32(iinfo->i_lenAlloc); |
1656 | efe->checkpoint = cpu_to_le32(iinfo->i_checkpoint); | ||
1649 | efe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EFE); | 1657 | efe->descTag.tagIdent = cpu_to_le16(TAG_IDENT_EFE); |
1650 | crclen = sizeof(struct extendedFileEntry); | 1658 | crclen = sizeof(struct extendedFileEntry); |
1651 | } | 1659 | } |
diff --git a/fs/udf/super.c b/fs/udf/super.c index 85067b4c7e14..ac8a348dcb69 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -950,11 +950,8 @@ static struct udf_bitmap *udf_sb_alloc_bitmap(struct super_block *sb, u32 index) | |||
950 | else | 950 | else |
951 | bitmap = vzalloc(size); /* TODO: get rid of vzalloc */ | 951 | bitmap = vzalloc(size); /* TODO: get rid of vzalloc */ |
952 | 952 | ||
953 | if (bitmap == NULL) { | 953 | if (bitmap == NULL) |
954 | udf_err(sb, "Unable to allocate space for bitmap and %d buffer_head pointers\n", | ||
955 | nr_groups); | ||
956 | return NULL; | 954 | return NULL; |
957 | } | ||
958 | 955 | ||
959 | bitmap->s_block_bitmap = (struct buffer_head **)(bitmap + 1); | 956 | bitmap->s_block_bitmap = (struct buffer_head **)(bitmap + 1); |
960 | bitmap->s_nr_groups = nr_groups; | 957 | bitmap->s_nr_groups = nr_groups; |
diff --git a/fs/udf/udf_i.h b/fs/udf/udf_i.h index d1bd31ea724e..bb8309dcd5c1 100644 --- a/fs/udf/udf_i.h +++ b/fs/udf/udf_i.h | |||
@@ -23,6 +23,7 @@ struct udf_inode_info { | |||
23 | __u64 i_lenExtents; | 23 | __u64 i_lenExtents; |
24 | __u32 i_next_alloc_block; | 24 | __u32 i_next_alloc_block; |
25 | __u32 i_next_alloc_goal; | 25 | __u32 i_next_alloc_goal; |
26 | __u32 i_checkpoint; | ||
26 | unsigned i_alloc_type : 3; | 27 | unsigned i_alloc_type : 3; |
27 | unsigned i_efe : 1; /* extendedFileEntry */ | 28 | unsigned i_efe : 1; /* extendedFileEntry */ |
28 | unsigned i_use : 1; /* unallocSpaceEntry */ | 29 | unsigned i_use : 1; /* unallocSpaceEntry */ |