diff options
Diffstat (limited to 'fs/ext3')
-rw-r--r-- | fs/ext3/acl.c | 2 | ||||
-rw-r--r-- | fs/ext3/balloc.c | 8 | ||||
-rw-r--r-- | fs/ext3/dir.c | 2 | ||||
-rw-r--r-- | fs/ext3/file.c | 2 | ||||
-rw-r--r-- | fs/ext3/ialloc.c | 12 | ||||
-rw-r--r-- | fs/ext3/inode.c | 157 | ||||
-rw-r--r-- | fs/ext3/ioctl.c | 59 | ||||
-rw-r--r-- | fs/ext3/namei.c | 35 | ||||
-rw-r--r-- | fs/ext3/super.c | 48 | ||||
-rw-r--r-- | fs/ext3/xattr.c | 6 |
10 files changed, 149 insertions, 182 deletions
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c index b60bb241880c..d81ef2fdb08e 100644 --- a/fs/ext3/acl.c +++ b/fs/ext3/acl.c | |||
@@ -323,7 +323,7 @@ ext3_init_acl(handle_t *handle, struct inode *inode, struct inode *dir) | |||
323 | return PTR_ERR(acl); | 323 | return PTR_ERR(acl); |
324 | } | 324 | } |
325 | if (!acl) | 325 | if (!acl) |
326 | inode->i_mode &= ~current->fs->umask; | 326 | inode->i_mode &= ~current_umask(); |
327 | } | 327 | } |
328 | if (test_opt(inode->i_sb, POSIX_ACL) && acl) { | 328 | if (test_opt(inode->i_sb, POSIX_ACL) && acl) { |
329 | struct posix_acl *clone; | 329 | struct posix_acl *clone; |
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c index 0dbf1c048475..225202db8974 100644 --- a/fs/ext3/balloc.c +++ b/fs/ext3/balloc.c | |||
@@ -676,7 +676,7 @@ void ext3_free_blocks(handle_t *handle, struct inode *inode, | |||
676 | } | 676 | } |
677 | ext3_free_blocks_sb(handle, sb, block, count, &dquot_freed_blocks); | 677 | ext3_free_blocks_sb(handle, sb, block, count, &dquot_freed_blocks); |
678 | if (dquot_freed_blocks) | 678 | if (dquot_freed_blocks) |
679 | DQUOT_FREE_BLOCK(inode, dquot_freed_blocks); | 679 | vfs_dq_free_block(inode, dquot_freed_blocks); |
680 | return; | 680 | return; |
681 | } | 681 | } |
682 | 682 | ||
@@ -1502,7 +1502,7 @@ ext3_fsblk_t ext3_new_blocks(handle_t *handle, struct inode *inode, | |||
1502 | /* | 1502 | /* |
1503 | * Check quota for allocation of this block. | 1503 | * Check quota for allocation of this block. |
1504 | */ | 1504 | */ |
1505 | if (DQUOT_ALLOC_BLOCK(inode, num)) { | 1505 | if (vfs_dq_alloc_block(inode, num)) { |
1506 | *errp = -EDQUOT; | 1506 | *errp = -EDQUOT; |
1507 | return 0; | 1507 | return 0; |
1508 | } | 1508 | } |
@@ -1714,7 +1714,7 @@ allocated: | |||
1714 | 1714 | ||
1715 | *errp = 0; | 1715 | *errp = 0; |
1716 | brelse(bitmap_bh); | 1716 | brelse(bitmap_bh); |
1717 | DQUOT_FREE_BLOCK(inode, *count-num); | 1717 | vfs_dq_free_block(inode, *count-num); |
1718 | *count = num; | 1718 | *count = num; |
1719 | return ret_block; | 1719 | return ret_block; |
1720 | 1720 | ||
@@ -1729,7 +1729,7 @@ out: | |||
1729 | * Undo the block allocation | 1729 | * Undo the block allocation |
1730 | */ | 1730 | */ |
1731 | if (!performed_allocation) | 1731 | if (!performed_allocation) |
1732 | DQUOT_FREE_BLOCK(inode, *count); | 1732 | vfs_dq_free_block(inode, *count); |
1733 | brelse(bitmap_bh); | 1733 | brelse(bitmap_bh); |
1734 | return 0; | 1734 | return 0; |
1735 | } | 1735 | } |
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c index 5853f4440af4..3d724a95882f 100644 --- a/fs/ext3/dir.c +++ b/fs/ext3/dir.c | |||
@@ -42,7 +42,7 @@ const struct file_operations ext3_dir_operations = { | |||
42 | .llseek = generic_file_llseek, | 42 | .llseek = generic_file_llseek, |
43 | .read = generic_read_dir, | 43 | .read = generic_read_dir, |
44 | .readdir = ext3_readdir, /* we take BKL. needed?*/ | 44 | .readdir = ext3_readdir, /* we take BKL. needed?*/ |
45 | .ioctl = ext3_ioctl, /* BKL held */ | 45 | .unlocked_ioctl = ext3_ioctl, |
46 | #ifdef CONFIG_COMPAT | 46 | #ifdef CONFIG_COMPAT |
47 | .compat_ioctl = ext3_compat_ioctl, | 47 | .compat_ioctl = ext3_compat_ioctl, |
48 | #endif | 48 | #endif |
diff --git a/fs/ext3/file.c b/fs/ext3/file.c index 4a04cbb1c231..5b49704b231b 100644 --- a/fs/ext3/file.c +++ b/fs/ext3/file.c | |||
@@ -116,7 +116,7 @@ const struct file_operations ext3_file_operations = { | |||
116 | .write = do_sync_write, | 116 | .write = do_sync_write, |
117 | .aio_read = generic_file_aio_read, | 117 | .aio_read = generic_file_aio_read, |
118 | .aio_write = ext3_file_write, | 118 | .aio_write = ext3_file_write, |
119 | .ioctl = ext3_ioctl, | 119 | .unlocked_ioctl = ext3_ioctl, |
120 | #ifdef CONFIG_COMPAT | 120 | #ifdef CONFIG_COMPAT |
121 | .compat_ioctl = ext3_compat_ioctl, | 121 | .compat_ioctl = ext3_compat_ioctl, |
122 | #endif | 122 | #endif |
diff --git a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c index 8de6c720e510..dd13d60d524b 100644 --- a/fs/ext3/ialloc.c +++ b/fs/ext3/ialloc.c | |||
@@ -123,10 +123,10 @@ void ext3_free_inode (handle_t *handle, struct inode * inode) | |||
123 | * Note: we must free any quota before locking the superblock, | 123 | * Note: we must free any quota before locking the superblock, |
124 | * as writing the quota to disk may need the lock as well. | 124 | * as writing the quota to disk may need the lock as well. |
125 | */ | 125 | */ |
126 | DQUOT_INIT(inode); | 126 | vfs_dq_init(inode); |
127 | ext3_xattr_delete_inode(handle, inode); | 127 | ext3_xattr_delete_inode(handle, inode); |
128 | DQUOT_FREE_INODE(inode); | 128 | vfs_dq_free_inode(inode); |
129 | DQUOT_DROP(inode); | 129 | vfs_dq_drop(inode); |
130 | 130 | ||
131 | is_directory = S_ISDIR(inode->i_mode); | 131 | is_directory = S_ISDIR(inode->i_mode); |
132 | 132 | ||
@@ -589,7 +589,7 @@ got: | |||
589 | sizeof(struct ext3_inode) - EXT3_GOOD_OLD_INODE_SIZE : 0; | 589 | sizeof(struct ext3_inode) - EXT3_GOOD_OLD_INODE_SIZE : 0; |
590 | 590 | ||
591 | ret = inode; | 591 | ret = inode; |
592 | if(DQUOT_ALLOC_INODE(inode)) { | 592 | if (vfs_dq_alloc_inode(inode)) { |
593 | err = -EDQUOT; | 593 | err = -EDQUOT; |
594 | goto fail_drop; | 594 | goto fail_drop; |
595 | } | 595 | } |
@@ -620,10 +620,10 @@ really_out: | |||
620 | return ret; | 620 | return ret; |
621 | 621 | ||
622 | fail_free_drop: | 622 | fail_free_drop: |
623 | DQUOT_FREE_INODE(inode); | 623 | vfs_dq_free_inode(inode); |
624 | 624 | ||
625 | fail_drop: | 625 | fail_drop: |
626 | DQUOT_DROP(inode); | 626 | vfs_dq_drop(inode); |
627 | inode->i_flags |= S_NOQUOTA; | 627 | inode->i_flags |= S_NOQUOTA; |
628 | inode->i_nlink = 0; | 628 | inode->i_nlink = 0; |
629 | unlock_new_inode(inode); | 629 | unlock_new_inode(inode); |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 0f5bca0d82fc..466a332e0bd1 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -1149,12 +1149,15 @@ static int ext3_write_begin(struct file *file, struct address_space *mapping, | |||
1149 | struct page **pagep, void **fsdata) | 1149 | struct page **pagep, void **fsdata) |
1150 | { | 1150 | { |
1151 | struct inode *inode = mapping->host; | 1151 | struct inode *inode = mapping->host; |
1152 | int ret, needed_blocks = ext3_writepage_trans_blocks(inode); | 1152 | int ret; |
1153 | handle_t *handle; | 1153 | handle_t *handle; |
1154 | int retries = 0; | 1154 | int retries = 0; |
1155 | struct page *page; | 1155 | struct page *page; |
1156 | pgoff_t index; | 1156 | pgoff_t index; |
1157 | unsigned from, to; | 1157 | unsigned from, to; |
1158 | /* Reserve one block more for addition to orphan list in case | ||
1159 | * we allocate blocks but write fails for some reason */ | ||
1160 | int needed_blocks = ext3_writepage_trans_blocks(inode) + 1; | ||
1158 | 1161 | ||
1159 | index = pos >> PAGE_CACHE_SHIFT; | 1162 | index = pos >> PAGE_CACHE_SHIFT; |
1160 | from = pos & (PAGE_CACHE_SIZE - 1); | 1163 | from = pos & (PAGE_CACHE_SIZE - 1); |
@@ -1184,15 +1187,20 @@ retry: | |||
1184 | } | 1187 | } |
1185 | write_begin_failed: | 1188 | write_begin_failed: |
1186 | if (ret) { | 1189 | if (ret) { |
1187 | ext3_journal_stop(handle); | ||
1188 | unlock_page(page); | ||
1189 | page_cache_release(page); | ||
1190 | /* | 1190 | /* |
1191 | * block_write_begin may have instantiated a few blocks | 1191 | * block_write_begin may have instantiated a few blocks |
1192 | * outside i_size. Trim these off again. Don't need | 1192 | * outside i_size. Trim these off again. Don't need |
1193 | * i_size_read because we hold i_mutex. | 1193 | * i_size_read because we hold i_mutex. |
1194 | * | ||
1195 | * Add inode to orphan list in case we crash before truncate | ||
1196 | * finishes. | ||
1194 | */ | 1197 | */ |
1195 | if (pos + len > inode->i_size) | 1198 | if (pos + len > inode->i_size) |
1199 | ext3_orphan_add(handle, inode); | ||
1200 | ext3_journal_stop(handle); | ||
1201 | unlock_page(page); | ||
1202 | page_cache_release(page); | ||
1203 | if (pos + len > inode->i_size) | ||
1196 | vmtruncate(inode, inode->i_size); | 1204 | vmtruncate(inode, inode->i_size); |
1197 | } | 1205 | } |
1198 | if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries)) | 1206 | if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries)) |
@@ -1211,6 +1219,18 @@ int ext3_journal_dirty_data(handle_t *handle, struct buffer_head *bh) | |||
1211 | return err; | 1219 | return err; |
1212 | } | 1220 | } |
1213 | 1221 | ||
1222 | /* For ordered writepage and write_end functions */ | ||
1223 | static int journal_dirty_data_fn(handle_t *handle, struct buffer_head *bh) | ||
1224 | { | ||
1225 | /* | ||
1226 | * Write could have mapped the buffer but it didn't copy the data in | ||
1227 | * yet. So avoid filing such buffer into a transaction. | ||
1228 | */ | ||
1229 | if (buffer_mapped(bh) && buffer_uptodate(bh)) | ||
1230 | return ext3_journal_dirty_data(handle, bh); | ||
1231 | return 0; | ||
1232 | } | ||
1233 | |||
1214 | /* For write_end() in data=journal mode */ | 1234 | /* For write_end() in data=journal mode */ |
1215 | static int write_end_fn(handle_t *handle, struct buffer_head *bh) | 1235 | static int write_end_fn(handle_t *handle, struct buffer_head *bh) |
1216 | { | 1236 | { |
@@ -1221,26 +1241,20 @@ static int write_end_fn(handle_t *handle, struct buffer_head *bh) | |||
1221 | } | 1241 | } |
1222 | 1242 | ||
1223 | /* | 1243 | /* |
1224 | * Generic write_end handler for ordered and writeback ext3 journal modes. | 1244 | * This is nasty and subtle: ext3_write_begin() could have allocated blocks |
1225 | * We can't use generic_write_end, because that unlocks the page and we need to | 1245 | * for the whole page but later we failed to copy the data in. Update inode |
1226 | * unlock the page after ext3_journal_stop, but ext3_journal_stop must run | 1246 | * size according to what we managed to copy. The rest is going to be |
1227 | * after block_write_end. | 1247 | * truncated in write_end function. |
1228 | */ | 1248 | */ |
1229 | static int ext3_generic_write_end(struct file *file, | 1249 | static void update_file_sizes(struct inode *inode, loff_t pos, unsigned copied) |
1230 | struct address_space *mapping, | ||
1231 | loff_t pos, unsigned len, unsigned copied, | ||
1232 | struct page *page, void *fsdata) | ||
1233 | { | 1250 | { |
1234 | struct inode *inode = file->f_mapping->host; | 1251 | /* What matters to us is i_disksize. We don't write i_size anywhere */ |
1235 | 1252 | if (pos + copied > inode->i_size) | |
1236 | copied = block_write_end(file, mapping, pos, len, copied, page, fsdata); | 1253 | i_size_write(inode, pos + copied); |
1237 | 1254 | if (pos + copied > EXT3_I(inode)->i_disksize) { | |
1238 | if (pos+copied > inode->i_size) { | 1255 | EXT3_I(inode)->i_disksize = pos + copied; |
1239 | i_size_write(inode, pos+copied); | ||
1240 | mark_inode_dirty(inode); | 1256 | mark_inode_dirty(inode); |
1241 | } | 1257 | } |
1242 | |||
1243 | return copied; | ||
1244 | } | 1258 | } |
1245 | 1259 | ||
1246 | /* | 1260 | /* |
@@ -1260,35 +1274,29 @@ static int ext3_ordered_write_end(struct file *file, | |||
1260 | unsigned from, to; | 1274 | unsigned from, to; |
1261 | int ret = 0, ret2; | 1275 | int ret = 0, ret2; |
1262 | 1276 | ||
1263 | from = pos & (PAGE_CACHE_SIZE - 1); | 1277 | copied = block_write_end(file, mapping, pos, len, copied, page, fsdata); |
1264 | to = from + len; | ||
1265 | 1278 | ||
1279 | from = pos & (PAGE_CACHE_SIZE - 1); | ||
1280 | to = from + copied; | ||
1266 | ret = walk_page_buffers(handle, page_buffers(page), | 1281 | ret = walk_page_buffers(handle, page_buffers(page), |
1267 | from, to, NULL, ext3_journal_dirty_data); | 1282 | from, to, NULL, journal_dirty_data_fn); |
1268 | 1283 | ||
1269 | if (ret == 0) { | 1284 | if (ret == 0) |
1270 | /* | 1285 | update_file_sizes(inode, pos, copied); |
1271 | * generic_write_end() will run mark_inode_dirty() if i_size | 1286 | /* |
1272 | * changes. So let's piggyback the i_disksize mark_inode_dirty | 1287 | * There may be allocated blocks outside of i_size because |
1273 | * into that. | 1288 | * we failed to copy some data. Prepare for truncate. |
1274 | */ | 1289 | */ |
1275 | loff_t new_i_size; | 1290 | if (pos + len > inode->i_size) |
1276 | 1291 | ext3_orphan_add(handle, inode); | |
1277 | new_i_size = pos + copied; | ||
1278 | if (new_i_size > EXT3_I(inode)->i_disksize) | ||
1279 | EXT3_I(inode)->i_disksize = new_i_size; | ||
1280 | ret2 = ext3_generic_write_end(file, mapping, pos, len, copied, | ||
1281 | page, fsdata); | ||
1282 | copied = ret2; | ||
1283 | if (ret2 < 0) | ||
1284 | ret = ret2; | ||
1285 | } | ||
1286 | ret2 = ext3_journal_stop(handle); | 1292 | ret2 = ext3_journal_stop(handle); |
1287 | if (!ret) | 1293 | if (!ret) |
1288 | ret = ret2; | 1294 | ret = ret2; |
1289 | unlock_page(page); | 1295 | unlock_page(page); |
1290 | page_cache_release(page); | 1296 | page_cache_release(page); |
1291 | 1297 | ||
1298 | if (pos + len > inode->i_size) | ||
1299 | vmtruncate(inode, inode->i_size); | ||
1292 | return ret ? ret : copied; | 1300 | return ret ? ret : copied; |
1293 | } | 1301 | } |
1294 | 1302 | ||
@@ -1299,25 +1307,22 @@ static int ext3_writeback_write_end(struct file *file, | |||
1299 | { | 1307 | { |
1300 | handle_t *handle = ext3_journal_current_handle(); | 1308 | handle_t *handle = ext3_journal_current_handle(); |
1301 | struct inode *inode = file->f_mapping->host; | 1309 | struct inode *inode = file->f_mapping->host; |
1302 | int ret = 0, ret2; | 1310 | int ret; |
1303 | loff_t new_i_size; | ||
1304 | |||
1305 | new_i_size = pos + copied; | ||
1306 | if (new_i_size > EXT3_I(inode)->i_disksize) | ||
1307 | EXT3_I(inode)->i_disksize = new_i_size; | ||
1308 | |||
1309 | ret2 = ext3_generic_write_end(file, mapping, pos, len, copied, | ||
1310 | page, fsdata); | ||
1311 | copied = ret2; | ||
1312 | if (ret2 < 0) | ||
1313 | ret = ret2; | ||
1314 | 1311 | ||
1315 | ret2 = ext3_journal_stop(handle); | 1312 | copied = block_write_end(file, mapping, pos, len, copied, page, fsdata); |
1316 | if (!ret) | 1313 | update_file_sizes(inode, pos, copied); |
1317 | ret = ret2; | 1314 | /* |
1315 | * There may be allocated blocks outside of i_size because | ||
1316 | * we failed to copy some data. Prepare for truncate. | ||
1317 | */ | ||
1318 | if (pos + len > inode->i_size) | ||
1319 | ext3_orphan_add(handle, inode); | ||
1320 | ret = ext3_journal_stop(handle); | ||
1318 | unlock_page(page); | 1321 | unlock_page(page); |
1319 | page_cache_release(page); | 1322 | page_cache_release(page); |
1320 | 1323 | ||
1324 | if (pos + len > inode->i_size) | ||
1325 | vmtruncate(inode, inode->i_size); | ||
1321 | return ret ? ret : copied; | 1326 | return ret ? ret : copied; |
1322 | } | 1327 | } |
1323 | 1328 | ||
@@ -1338,15 +1343,23 @@ static int ext3_journalled_write_end(struct file *file, | |||
1338 | if (copied < len) { | 1343 | if (copied < len) { |
1339 | if (!PageUptodate(page)) | 1344 | if (!PageUptodate(page)) |
1340 | copied = 0; | 1345 | copied = 0; |
1341 | page_zero_new_buffers(page, from+copied, to); | 1346 | page_zero_new_buffers(page, from + copied, to); |
1347 | to = from + copied; | ||
1342 | } | 1348 | } |
1343 | 1349 | ||
1344 | ret = walk_page_buffers(handle, page_buffers(page), from, | 1350 | ret = walk_page_buffers(handle, page_buffers(page), from, |
1345 | to, &partial, write_end_fn); | 1351 | to, &partial, write_end_fn); |
1346 | if (!partial) | 1352 | if (!partial) |
1347 | SetPageUptodate(page); | 1353 | SetPageUptodate(page); |
1348 | if (pos+copied > inode->i_size) | 1354 | |
1349 | i_size_write(inode, pos+copied); | 1355 | if (pos + copied > inode->i_size) |
1356 | i_size_write(inode, pos + copied); | ||
1357 | /* | ||
1358 | * There may be allocated blocks outside of i_size because | ||
1359 | * we failed to copy some data. Prepare for truncate. | ||
1360 | */ | ||
1361 | if (pos + len > inode->i_size) | ||
1362 | ext3_orphan_add(handle, inode); | ||
1350 | EXT3_I(inode)->i_state |= EXT3_STATE_JDATA; | 1363 | EXT3_I(inode)->i_state |= EXT3_STATE_JDATA; |
1351 | if (inode->i_size > EXT3_I(inode)->i_disksize) { | 1364 | if (inode->i_size > EXT3_I(inode)->i_disksize) { |
1352 | EXT3_I(inode)->i_disksize = inode->i_size; | 1365 | EXT3_I(inode)->i_disksize = inode->i_size; |
@@ -1361,6 +1374,8 @@ static int ext3_journalled_write_end(struct file *file, | |||
1361 | unlock_page(page); | 1374 | unlock_page(page); |
1362 | page_cache_release(page); | 1375 | page_cache_release(page); |
1363 | 1376 | ||
1377 | if (pos + len > inode->i_size) | ||
1378 | vmtruncate(inode, inode->i_size); | ||
1364 | return ret ? ret : copied; | 1379 | return ret ? ret : copied; |
1365 | } | 1380 | } |
1366 | 1381 | ||
@@ -1428,11 +1443,9 @@ static int bput_one(handle_t *handle, struct buffer_head *bh) | |||
1428 | return 0; | 1443 | return 0; |
1429 | } | 1444 | } |
1430 | 1445 | ||
1431 | static int journal_dirty_data_fn(handle_t *handle, struct buffer_head *bh) | 1446 | static int buffer_unmapped(handle_t *handle, struct buffer_head *bh) |
1432 | { | 1447 | { |
1433 | if (buffer_mapped(bh)) | 1448 | return !buffer_mapped(bh); |
1434 | return ext3_journal_dirty_data(handle, bh); | ||
1435 | return 0; | ||
1436 | } | 1449 | } |
1437 | 1450 | ||
1438 | /* | 1451 | /* |
@@ -1505,6 +1518,15 @@ static int ext3_ordered_writepage(struct page *page, | |||
1505 | if (ext3_journal_current_handle()) | 1518 | if (ext3_journal_current_handle()) |
1506 | goto out_fail; | 1519 | goto out_fail; |
1507 | 1520 | ||
1521 | if (!page_has_buffers(page)) { | ||
1522 | create_empty_buffers(page, inode->i_sb->s_blocksize, | ||
1523 | (1 << BH_Dirty)|(1 << BH_Uptodate)); | ||
1524 | } else if (!walk_page_buffers(NULL, page_buffers(page), 0, PAGE_CACHE_SIZE, NULL, buffer_unmapped)) { | ||
1525 | /* Provide NULL instead of get_block so that we catch bugs if buffers weren't really mapped */ | ||
1526 | return block_write_full_page(page, NULL, wbc); | ||
1527 | } | ||
1528 | page_bufs = page_buffers(page); | ||
1529 | |||
1508 | handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode)); | 1530 | handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode)); |
1509 | 1531 | ||
1510 | if (IS_ERR(handle)) { | 1532 | if (IS_ERR(handle)) { |
@@ -1512,11 +1534,6 @@ static int ext3_ordered_writepage(struct page *page, | |||
1512 | goto out_fail; | 1534 | goto out_fail; |
1513 | } | 1535 | } |
1514 | 1536 | ||
1515 | if (!page_has_buffers(page)) { | ||
1516 | create_empty_buffers(page, inode->i_sb->s_blocksize, | ||
1517 | (1 << BH_Dirty)|(1 << BH_Uptodate)); | ||
1518 | } | ||
1519 | page_bufs = page_buffers(page); | ||
1520 | walk_page_buffers(handle, page_bufs, 0, | 1537 | walk_page_buffers(handle, page_bufs, 0, |
1521 | PAGE_CACHE_SIZE, NULL, bget_one); | 1538 | PAGE_CACHE_SIZE, NULL, bget_one); |
1522 | 1539 | ||
@@ -3058,7 +3075,7 @@ int ext3_setattr(struct dentry *dentry, struct iattr *attr) | |||
3058 | error = PTR_ERR(handle); | 3075 | error = PTR_ERR(handle); |
3059 | goto err_out; | 3076 | goto err_out; |
3060 | } | 3077 | } |
3061 | error = DQUOT_TRANSFER(inode, attr) ? -EDQUOT : 0; | 3078 | error = vfs_dq_transfer(inode, attr) ? -EDQUOT : 0; |
3062 | if (error) { | 3079 | if (error) { |
3063 | ext3_journal_stop(handle); | 3080 | ext3_journal_stop(handle); |
3064 | return error; | 3081 | return error; |
@@ -3149,7 +3166,7 @@ static int ext3_writepage_trans_blocks(struct inode *inode) | |||
3149 | ret = 2 * (bpp + indirects) + 2; | 3166 | ret = 2 * (bpp + indirects) + 2; |
3150 | 3167 | ||
3151 | #ifdef CONFIG_QUOTA | 3168 | #ifdef CONFIG_QUOTA |
3152 | /* We know that structure was already allocated during DQUOT_INIT so | 3169 | /* We know that structure was already allocated during vfs_dq_init so |
3153 | * we will be updating only the data blocks + inodes */ | 3170 | * we will be updating only the data blocks + inodes */ |
3154 | ret += 2*EXT3_QUOTA_TRANS_BLOCKS(inode->i_sb); | 3171 | ret += 2*EXT3_QUOTA_TRANS_BLOCKS(inode->i_sb); |
3155 | #endif | 3172 | #endif |
@@ -3240,7 +3257,7 @@ int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode) | |||
3240 | * i_size has been changed by generic_commit_write() and we thus need | 3257 | * i_size has been changed by generic_commit_write() and we thus need |
3241 | * to include the updated inode in the current transaction. | 3258 | * to include the updated inode in the current transaction. |
3242 | * | 3259 | * |
3243 | * Also, DQUOT_ALLOC_SPACE() will always dirty the inode when blocks | 3260 | * Also, vfs_dq_alloc_space() will always dirty the inode when blocks |
3244 | * are allocated to the file. | 3261 | * are allocated to the file. |
3245 | * | 3262 | * |
3246 | * If the inode is marked synchronous, we don't honour that here - doing | 3263 | * If the inode is marked synchronous, we don't honour that here - doing |
diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c index 5e86ce9a86e0..88974814783a 100644 --- a/fs/ext3/ioctl.c +++ b/fs/ext3/ioctl.c | |||
@@ -15,12 +15,11 @@ | |||
15 | #include <linux/mount.h> | 15 | #include <linux/mount.h> |
16 | #include <linux/time.h> | 16 | #include <linux/time.h> |
17 | #include <linux/compat.h> | 17 | #include <linux/compat.h> |
18 | #include <linux/smp_lock.h> | ||
19 | #include <asm/uaccess.h> | 18 | #include <asm/uaccess.h> |
20 | 19 | ||
21 | int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | 20 | long ext3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
22 | unsigned long arg) | ||
23 | { | 21 | { |
22 | struct inode *inode = filp->f_dentry->d_inode; | ||
24 | struct ext3_inode_info *ei = EXT3_I(inode); | 23 | struct ext3_inode_info *ei = EXT3_I(inode); |
25 | unsigned int flags; | 24 | unsigned int flags; |
26 | unsigned short rsv_window_size; | 25 | unsigned short rsv_window_size; |
@@ -39,29 +38,25 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
39 | unsigned int oldflags; | 38 | unsigned int oldflags; |
40 | unsigned int jflag; | 39 | unsigned int jflag; |
41 | 40 | ||
41 | if (!is_owner_or_cap(inode)) | ||
42 | return -EACCES; | ||
43 | |||
44 | if (get_user(flags, (int __user *) arg)) | ||
45 | return -EFAULT; | ||
46 | |||
42 | err = mnt_want_write(filp->f_path.mnt); | 47 | err = mnt_want_write(filp->f_path.mnt); |
43 | if (err) | 48 | if (err) |
44 | return err; | 49 | return err; |
45 | 50 | ||
46 | if (!is_owner_or_cap(inode)) { | ||
47 | err = -EACCES; | ||
48 | goto flags_out; | ||
49 | } | ||
50 | |||
51 | if (get_user(flags, (int __user *) arg)) { | ||
52 | err = -EFAULT; | ||
53 | goto flags_out; | ||
54 | } | ||
55 | |||
56 | flags = ext3_mask_flags(inode->i_mode, flags); | 51 | flags = ext3_mask_flags(inode->i_mode, flags); |
57 | 52 | ||
58 | mutex_lock(&inode->i_mutex); | 53 | mutex_lock(&inode->i_mutex); |
54 | |||
59 | /* Is it quota file? Do not allow user to mess with it */ | 55 | /* Is it quota file? Do not allow user to mess with it */ |
60 | if (IS_NOQUOTA(inode)) { | 56 | err = -EPERM; |
61 | mutex_unlock(&inode->i_mutex); | 57 | if (IS_NOQUOTA(inode)) |
62 | err = -EPERM; | ||
63 | goto flags_out; | 58 | goto flags_out; |
64 | } | 59 | |
65 | oldflags = ei->i_flags; | 60 | oldflags = ei->i_flags; |
66 | 61 | ||
67 | /* The JOURNAL_DATA flag is modifiable only by root */ | 62 | /* The JOURNAL_DATA flag is modifiable only by root */ |
@@ -74,11 +69,8 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
74 | * This test looks nicer. Thanks to Pauline Middelink | 69 | * This test looks nicer. Thanks to Pauline Middelink |
75 | */ | 70 | */ |
76 | if ((flags ^ oldflags) & (EXT3_APPEND_FL | EXT3_IMMUTABLE_FL)) { | 71 | if ((flags ^ oldflags) & (EXT3_APPEND_FL | EXT3_IMMUTABLE_FL)) { |
77 | if (!capable(CAP_LINUX_IMMUTABLE)) { | 72 | if (!capable(CAP_LINUX_IMMUTABLE)) |
78 | mutex_unlock(&inode->i_mutex); | ||
79 | err = -EPERM; | ||
80 | goto flags_out; | 73 | goto flags_out; |
81 | } | ||
82 | } | 74 | } |
83 | 75 | ||
84 | /* | 76 | /* |
@@ -86,17 +78,12 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
86 | * the relevant capability. | 78 | * the relevant capability. |
87 | */ | 79 | */ |
88 | if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL)) { | 80 | if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL)) { |
89 | if (!capable(CAP_SYS_RESOURCE)) { | 81 | if (!capable(CAP_SYS_RESOURCE)) |
90 | mutex_unlock(&inode->i_mutex); | ||
91 | err = -EPERM; | ||
92 | goto flags_out; | 82 | goto flags_out; |
93 | } | ||
94 | } | 83 | } |
95 | 84 | ||
96 | |||
97 | handle = ext3_journal_start(inode, 1); | 85 | handle = ext3_journal_start(inode, 1); |
98 | if (IS_ERR(handle)) { | 86 | if (IS_ERR(handle)) { |
99 | mutex_unlock(&inode->i_mutex); | ||
100 | err = PTR_ERR(handle); | 87 | err = PTR_ERR(handle); |
101 | goto flags_out; | 88 | goto flags_out; |
102 | } | 89 | } |
@@ -116,15 +103,13 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
116 | err = ext3_mark_iloc_dirty(handle, inode, &iloc); | 103 | err = ext3_mark_iloc_dirty(handle, inode, &iloc); |
117 | flags_err: | 104 | flags_err: |
118 | ext3_journal_stop(handle); | 105 | ext3_journal_stop(handle); |
119 | if (err) { | 106 | if (err) |
120 | mutex_unlock(&inode->i_mutex); | 107 | goto flags_out; |
121 | return err; | ||
122 | } | ||
123 | 108 | ||
124 | if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL)) | 109 | if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL)) |
125 | err = ext3_change_inode_journal_flag(inode, jflag); | 110 | err = ext3_change_inode_journal_flag(inode, jflag); |
126 | mutex_unlock(&inode->i_mutex); | ||
127 | flags_out: | 111 | flags_out: |
112 | mutex_unlock(&inode->i_mutex); | ||
128 | mnt_drop_write(filp->f_path.mnt); | 113 | mnt_drop_write(filp->f_path.mnt); |
129 | return err; | 114 | return err; |
130 | } | 115 | } |
@@ -140,6 +125,7 @@ flags_out: | |||
140 | 125 | ||
141 | if (!is_owner_or_cap(inode)) | 126 | if (!is_owner_or_cap(inode)) |
142 | return -EPERM; | 127 | return -EPERM; |
128 | |||
143 | err = mnt_want_write(filp->f_path.mnt); | 129 | err = mnt_want_write(filp->f_path.mnt); |
144 | if (err) | 130 | if (err) |
145 | return err; | 131 | return err; |
@@ -147,6 +133,7 @@ flags_out: | |||
147 | err = -EFAULT; | 133 | err = -EFAULT; |
148 | goto setversion_out; | 134 | goto setversion_out; |
149 | } | 135 | } |
136 | |||
150 | handle = ext3_journal_start(inode, 1); | 137 | handle = ext3_journal_start(inode, 1); |
151 | if (IS_ERR(handle)) { | 138 | if (IS_ERR(handle)) { |
152 | err = PTR_ERR(handle); | 139 | err = PTR_ERR(handle); |
@@ -299,9 +286,6 @@ group_add_out: | |||
299 | #ifdef CONFIG_COMPAT | 286 | #ifdef CONFIG_COMPAT |
300 | long ext3_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | 287 | long ext3_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) |
301 | { | 288 | { |
302 | struct inode *inode = file->f_path.dentry->d_inode; | ||
303 | int ret; | ||
304 | |||
305 | /* These are just misnamed, they actually get/put from/to user an int */ | 289 | /* These are just misnamed, they actually get/put from/to user an int */ |
306 | switch (cmd) { | 290 | switch (cmd) { |
307 | case EXT3_IOC32_GETFLAGS: | 291 | case EXT3_IOC32_GETFLAGS: |
@@ -341,9 +325,6 @@ long ext3_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
341 | default: | 325 | default: |
342 | return -ENOIOCTLCMD; | 326 | return -ENOIOCTLCMD; |
343 | } | 327 | } |
344 | lock_kernel(); | 328 | return ext3_ioctl(file, cmd, (unsigned long) compat_ptr(arg)); |
345 | ret = ext3_ioctl(inode, file, cmd, (unsigned long) compat_ptr(arg)); | ||
346 | unlock_kernel(); | ||
347 | return ret; | ||
348 | } | 329 | } |
349 | #endif | 330 | #endif |
diff --git a/fs/ext3/namei.c b/fs/ext3/namei.c index ab98a66ab8c7..6ff7b9730234 100644 --- a/fs/ext3/namei.c +++ b/fs/ext3/namei.c | |||
@@ -161,12 +161,12 @@ static struct dx_frame *dx_probe(struct qstr *entry, | |||
161 | struct dx_frame *frame, | 161 | struct dx_frame *frame, |
162 | int *err); | 162 | int *err); |
163 | static void dx_release (struct dx_frame *frames); | 163 | static void dx_release (struct dx_frame *frames); |
164 | static int dx_make_map (struct ext3_dir_entry_2 *de, int size, | 164 | static int dx_make_map(struct ext3_dir_entry_2 *de, unsigned blocksize, |
165 | struct dx_hash_info *hinfo, struct dx_map_entry map[]); | 165 | struct dx_hash_info *hinfo, struct dx_map_entry map[]); |
166 | static void dx_sort_map(struct dx_map_entry *map, unsigned count); | 166 | static void dx_sort_map(struct dx_map_entry *map, unsigned count); |
167 | static struct ext3_dir_entry_2 *dx_move_dirents (char *from, char *to, | 167 | static struct ext3_dir_entry_2 *dx_move_dirents (char *from, char *to, |
168 | struct dx_map_entry *offsets, int count); | 168 | struct dx_map_entry *offsets, int count); |
169 | static struct ext3_dir_entry_2* dx_pack_dirents (char *base, int size); | 169 | static struct ext3_dir_entry_2 *dx_pack_dirents(char *base, unsigned blocksize); |
170 | static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block); | 170 | static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block); |
171 | static int ext3_htree_next_block(struct inode *dir, __u32 hash, | 171 | static int ext3_htree_next_block(struct inode *dir, __u32 hash, |
172 | struct dx_frame *frame, | 172 | struct dx_frame *frame, |
@@ -708,14 +708,14 @@ errout: | |||
708 | * Create map of hash values, offsets, and sizes, stored at end of block. | 708 | * Create map of hash values, offsets, and sizes, stored at end of block. |
709 | * Returns number of entries mapped. | 709 | * Returns number of entries mapped. |
710 | */ | 710 | */ |
711 | static int dx_make_map (struct ext3_dir_entry_2 *de, int size, | 711 | static int dx_make_map(struct ext3_dir_entry_2 *de, unsigned blocksize, |
712 | struct dx_hash_info *hinfo, struct dx_map_entry *map_tail) | 712 | struct dx_hash_info *hinfo, struct dx_map_entry *map_tail) |
713 | { | 713 | { |
714 | int count = 0; | 714 | int count = 0; |
715 | char *base = (char *) de; | 715 | char *base = (char *) de; |
716 | struct dx_hash_info h = *hinfo; | 716 | struct dx_hash_info h = *hinfo; |
717 | 717 | ||
718 | while ((char *) de < base + size) | 718 | while ((char *) de < base + blocksize) |
719 | { | 719 | { |
720 | if (de->name_len && de->inode) { | 720 | if (de->name_len && de->inode) { |
721 | ext3fs_dirhash(de->name, de->name_len, &h); | 721 | ext3fs_dirhash(de->name, de->name_len, &h); |
@@ -1047,8 +1047,16 @@ static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry, str | |||
1047 | return ERR_PTR(-EIO); | 1047 | return ERR_PTR(-EIO); |
1048 | } | 1048 | } |
1049 | inode = ext3_iget(dir->i_sb, ino); | 1049 | inode = ext3_iget(dir->i_sb, ino); |
1050 | if (IS_ERR(inode)) | 1050 | if (unlikely(IS_ERR(inode))) { |
1051 | return ERR_CAST(inode); | 1051 | if (PTR_ERR(inode) == -ESTALE) { |
1052 | ext3_error(dir->i_sb, __func__, | ||
1053 | "deleted inode referenced: %lu", | ||
1054 | ino); | ||
1055 | return ERR_PTR(-EIO); | ||
1056 | } else { | ||
1057 | return ERR_CAST(inode); | ||
1058 | } | ||
1059 | } | ||
1052 | } | 1060 | } |
1053 | return d_splice_alias(inode, dentry); | 1061 | return d_splice_alias(inode, dentry); |
1054 | } | 1062 | } |
@@ -1120,13 +1128,14 @@ dx_move_dirents(char *from, char *to, struct dx_map_entry *map, int count) | |||
1120 | * Compact each dir entry in the range to the minimal rec_len. | 1128 | * Compact each dir entry in the range to the minimal rec_len. |
1121 | * Returns pointer to last entry in range. | 1129 | * Returns pointer to last entry in range. |
1122 | */ | 1130 | */ |
1123 | static struct ext3_dir_entry_2* dx_pack_dirents(char *base, int size) | 1131 | static struct ext3_dir_entry_2 *dx_pack_dirents(char *base, unsigned blocksize) |
1124 | { | 1132 | { |
1125 | struct ext3_dir_entry_2 *next, *to, *prev, *de = (struct ext3_dir_entry_2 *) base; | 1133 | struct ext3_dir_entry_2 *next, *to, *prev; |
1134 | struct ext3_dir_entry_2 *de = (struct ext3_dir_entry_2 *)base; | ||
1126 | unsigned rec_len = 0; | 1135 | unsigned rec_len = 0; |
1127 | 1136 | ||
1128 | prev = to = de; | 1137 | prev = to = de; |
1129 | while ((char*)de < base + size) { | 1138 | while ((char *)de < base + blocksize) { |
1130 | next = ext3_next_entry(de); | 1139 | next = ext3_next_entry(de); |
1131 | if (de->inode && de->name_len) { | 1140 | if (de->inode && de->name_len) { |
1132 | rec_len = EXT3_DIR_REC_LEN(de->name_len); | 1141 | rec_len = EXT3_DIR_REC_LEN(de->name_len); |
@@ -2049,7 +2058,7 @@ static int ext3_rmdir (struct inode * dir, struct dentry *dentry) | |||
2049 | 2058 | ||
2050 | /* Initialize quotas before so that eventual writes go in | 2059 | /* Initialize quotas before so that eventual writes go in |
2051 | * separate transaction */ | 2060 | * separate transaction */ |
2052 | DQUOT_INIT(dentry->d_inode); | 2061 | vfs_dq_init(dentry->d_inode); |
2053 | handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS(dir->i_sb)); | 2062 | handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS(dir->i_sb)); |
2054 | if (IS_ERR(handle)) | 2063 | if (IS_ERR(handle)) |
2055 | return PTR_ERR(handle); | 2064 | return PTR_ERR(handle); |
@@ -2108,7 +2117,7 @@ static int ext3_unlink(struct inode * dir, struct dentry *dentry) | |||
2108 | 2117 | ||
2109 | /* Initialize quotas before so that eventual writes go | 2118 | /* Initialize quotas before so that eventual writes go |
2110 | * in separate transaction */ | 2119 | * in separate transaction */ |
2111 | DQUOT_INIT(dentry->d_inode); | 2120 | vfs_dq_init(dentry->d_inode); |
2112 | handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS(dir->i_sb)); | 2121 | handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS(dir->i_sb)); |
2113 | if (IS_ERR(handle)) | 2122 | if (IS_ERR(handle)) |
2114 | return PTR_ERR(handle); | 2123 | return PTR_ERR(handle); |
@@ -2272,7 +2281,7 @@ static int ext3_rename (struct inode * old_dir, struct dentry *old_dentry, | |||
2272 | /* Initialize quotas before so that eventual writes go | 2281 | /* Initialize quotas before so that eventual writes go |
2273 | * in separate transaction */ | 2282 | * in separate transaction */ |
2274 | if (new_dentry->d_inode) | 2283 | if (new_dentry->d_inode) |
2275 | DQUOT_INIT(new_dentry->d_inode); | 2284 | vfs_dq_init(new_dentry->d_inode); |
2276 | handle = ext3_journal_start(old_dir, 2 * | 2285 | handle = ext3_journal_start(old_dir, 2 * |
2277 | EXT3_DATA_TRANS_BLOCKS(old_dir->i_sb) + | 2286 | EXT3_DATA_TRANS_BLOCKS(old_dir->i_sb) + |
2278 | EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2); | 2287 | EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2); |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 4a970411a458..9e5b8e387e1e 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -707,8 +707,6 @@ static int bdev_try_to_free_page(struct super_block *sb, struct page *page, | |||
707 | #define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group") | 707 | #define QTYPE2NAME(t) ((t)==USRQUOTA?"user":"group") |
708 | #define QTYPE2MOPT(on, t) ((t)==USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA)) | 708 | #define QTYPE2MOPT(on, t) ((t)==USRQUOTA?((on)##USRJQUOTA):((on)##GRPJQUOTA)) |
709 | 709 | ||
710 | static int ext3_dquot_initialize(struct inode *inode, int type); | ||
711 | static int ext3_dquot_drop(struct inode *inode); | ||
712 | static int ext3_write_dquot(struct dquot *dquot); | 710 | static int ext3_write_dquot(struct dquot *dquot); |
713 | static int ext3_acquire_dquot(struct dquot *dquot); | 711 | static int ext3_acquire_dquot(struct dquot *dquot); |
714 | static int ext3_release_dquot(struct dquot *dquot); | 712 | static int ext3_release_dquot(struct dquot *dquot); |
@@ -723,8 +721,8 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type, | |||
723 | const char *data, size_t len, loff_t off); | 721 | const char *data, size_t len, loff_t off); |
724 | 722 | ||
725 | static struct dquot_operations ext3_quota_operations = { | 723 | static struct dquot_operations ext3_quota_operations = { |
726 | .initialize = ext3_dquot_initialize, | 724 | .initialize = dquot_initialize, |
727 | .drop = ext3_dquot_drop, | 725 | .drop = dquot_drop, |
728 | .alloc_space = dquot_alloc_space, | 726 | .alloc_space = dquot_alloc_space, |
729 | .alloc_inode = dquot_alloc_inode, | 727 | .alloc_inode = dquot_alloc_inode, |
730 | .free_space = dquot_free_space, | 728 | .free_space = dquot_free_space, |
@@ -1438,7 +1436,7 @@ static void ext3_orphan_cleanup (struct super_block * sb, | |||
1438 | } | 1436 | } |
1439 | 1437 | ||
1440 | list_add(&EXT3_I(inode)->i_orphan, &EXT3_SB(sb)->s_orphan); | 1438 | list_add(&EXT3_I(inode)->i_orphan, &EXT3_SB(sb)->s_orphan); |
1441 | DQUOT_INIT(inode); | 1439 | vfs_dq_init(inode); |
1442 | if (inode->i_nlink) { | 1440 | if (inode->i_nlink) { |
1443 | printk(KERN_DEBUG | 1441 | printk(KERN_DEBUG |
1444 | "%s: truncating inode %lu to %Ld bytes\n", | 1442 | "%s: truncating inode %lu to %Ld bytes\n", |
@@ -2702,7 +2700,7 @@ static int ext3_statfs (struct dentry * dentry, struct kstatfs * buf) | |||
2702 | * Process 1 Process 2 | 2700 | * Process 1 Process 2 |
2703 | * ext3_create() quota_sync() | 2701 | * ext3_create() quota_sync() |
2704 | * journal_start() write_dquot() | 2702 | * journal_start() write_dquot() |
2705 | * DQUOT_INIT() down(dqio_mutex) | 2703 | * vfs_dq_init() down(dqio_mutex) |
2706 | * down(dqio_mutex) journal_start() | 2704 | * down(dqio_mutex) journal_start() |
2707 | * | 2705 | * |
2708 | */ | 2706 | */ |
@@ -2714,44 +2712,6 @@ static inline struct inode *dquot_to_inode(struct dquot *dquot) | |||
2714 | return sb_dqopt(dquot->dq_sb)->files[dquot->dq_type]; | 2712 | return sb_dqopt(dquot->dq_sb)->files[dquot->dq_type]; |
2715 | } | 2713 | } |
2716 | 2714 | ||
2717 | static int ext3_dquot_initialize(struct inode *inode, int type) | ||
2718 | { | ||
2719 | handle_t *handle; | ||
2720 | int ret, err; | ||
2721 | |||
2722 | /* We may create quota structure so we need to reserve enough blocks */ | ||
2723 | handle = ext3_journal_start(inode, 2*EXT3_QUOTA_INIT_BLOCKS(inode->i_sb)); | ||
2724 | if (IS_ERR(handle)) | ||
2725 | return PTR_ERR(handle); | ||
2726 | ret = dquot_initialize(inode, type); | ||
2727 | err = ext3_journal_stop(handle); | ||
2728 | if (!ret) | ||
2729 | ret = err; | ||
2730 | return ret; | ||
2731 | } | ||
2732 | |||
2733 | static int ext3_dquot_drop(struct inode *inode) | ||
2734 | { | ||
2735 | handle_t *handle; | ||
2736 | int ret, err; | ||
2737 | |||
2738 | /* We may delete quota structure so we need to reserve enough blocks */ | ||
2739 | handle = ext3_journal_start(inode, 2*EXT3_QUOTA_DEL_BLOCKS(inode->i_sb)); | ||
2740 | if (IS_ERR(handle)) { | ||
2741 | /* | ||
2742 | * We call dquot_drop() anyway to at least release references | ||
2743 | * to quota structures so that umount does not hang. | ||
2744 | */ | ||
2745 | dquot_drop(inode); | ||
2746 | return PTR_ERR(handle); | ||
2747 | } | ||
2748 | ret = dquot_drop(inode); | ||
2749 | err = ext3_journal_stop(handle); | ||
2750 | if (!ret) | ||
2751 | ret = err; | ||
2752 | return ret; | ||
2753 | } | ||
2754 | |||
2755 | static int ext3_write_dquot(struct dquot *dquot) | 2715 | static int ext3_write_dquot(struct dquot *dquot) |
2756 | { | 2716 | { |
2757 | int ret, err; | 2717 | int ret, err; |
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c index 175414ac2210..83b7be849bd5 100644 --- a/fs/ext3/xattr.c +++ b/fs/ext3/xattr.c | |||
@@ -498,7 +498,7 @@ ext3_xattr_release_block(handle_t *handle, struct inode *inode, | |||
498 | error = ext3_journal_dirty_metadata(handle, bh); | 498 | error = ext3_journal_dirty_metadata(handle, bh); |
499 | if (IS_SYNC(inode)) | 499 | if (IS_SYNC(inode)) |
500 | handle->h_sync = 1; | 500 | handle->h_sync = 1; |
501 | DQUOT_FREE_BLOCK(inode, 1); | 501 | vfs_dq_free_block(inode, 1); |
502 | ea_bdebug(bh, "refcount now=%d; releasing", | 502 | ea_bdebug(bh, "refcount now=%d; releasing", |
503 | le32_to_cpu(BHDR(bh)->h_refcount)); | 503 | le32_to_cpu(BHDR(bh)->h_refcount)); |
504 | if (ce) | 504 | if (ce) |
@@ -774,7 +774,7 @@ inserted: | |||
774 | /* The old block is released after updating | 774 | /* The old block is released after updating |
775 | the inode. */ | 775 | the inode. */ |
776 | error = -EDQUOT; | 776 | error = -EDQUOT; |
777 | if (DQUOT_ALLOC_BLOCK(inode, 1)) | 777 | if (vfs_dq_alloc_block(inode, 1)) |
778 | goto cleanup; | 778 | goto cleanup; |
779 | error = ext3_journal_get_write_access(handle, | 779 | error = ext3_journal_get_write_access(handle, |
780 | new_bh); | 780 | new_bh); |
@@ -848,7 +848,7 @@ cleanup: | |||
848 | return error; | 848 | return error; |
849 | 849 | ||
850 | cleanup_dquot: | 850 | cleanup_dquot: |
851 | DQUOT_FREE_BLOCK(inode, 1); | 851 | vfs_dq_free_block(inode, 1); |
852 | goto cleanup; | 852 | goto cleanup; |
853 | 853 | ||
854 | bad_block: | 854 | bad_block: |