diff options
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r-- | fs/ext4/super.c | 361 |
1 files changed, 222 insertions, 139 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 735c20d5fd56..ba191dae8730 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -302,7 +302,7 @@ void ext4_journal_abort_handle(const char *caller, const char *err_fn, | |||
302 | * write out the superblock safely. | 302 | * write out the superblock safely. |
303 | * | 303 | * |
304 | * We'll just use the jbd2_journal_abort() error code to record an error in | 304 | * We'll just use the jbd2_journal_abort() error code to record an error in |
305 | * the journal instead. On recovery, the journal will compain about | 305 | * the journal instead. On recovery, the journal will complain about |
306 | * that error until we've noted it down and cleared it. | 306 | * that error until we've noted it down and cleared it. |
307 | */ | 307 | */ |
308 | 308 | ||
@@ -333,7 +333,7 @@ static void ext4_handle_error(struct super_block *sb) | |||
333 | sb->s_id); | 333 | sb->s_id); |
334 | } | 334 | } |
335 | 335 | ||
336 | void ext4_error(struct super_block *sb, const char *function, | 336 | void __ext4_error(struct super_block *sb, const char *function, |
337 | const char *fmt, ...) | 337 | const char *fmt, ...) |
338 | { | 338 | { |
339 | va_list args; | 339 | va_list args; |
@@ -347,6 +347,42 @@ void ext4_error(struct super_block *sb, const char *function, | |||
347 | ext4_handle_error(sb); | 347 | ext4_handle_error(sb); |
348 | } | 348 | } |
349 | 349 | ||
350 | void ext4_error_inode(const char *function, struct inode *inode, | ||
351 | const char *fmt, ...) | ||
352 | { | ||
353 | va_list args; | ||
354 | |||
355 | va_start(args, fmt); | ||
356 | printk(KERN_CRIT "EXT4-fs error (device %s): %s: inode #%lu: (comm %s) ", | ||
357 | inode->i_sb->s_id, function, inode->i_ino, current->comm); | ||
358 | vprintk(fmt, args); | ||
359 | printk("\n"); | ||
360 | va_end(args); | ||
361 | |||
362 | ext4_handle_error(inode->i_sb); | ||
363 | } | ||
364 | |||
365 | void ext4_error_file(const char *function, struct file *file, | ||
366 | const char *fmt, ...) | ||
367 | { | ||
368 | va_list args; | ||
369 | struct inode *inode = file->f_dentry->d_inode; | ||
370 | char pathname[80], *path; | ||
371 | |||
372 | va_start(args, fmt); | ||
373 | path = d_path(&(file->f_path), pathname, sizeof(pathname)); | ||
374 | if (!path) | ||
375 | path = "(unknown)"; | ||
376 | printk(KERN_CRIT | ||
377 | "EXT4-fs error (device %s): %s: inode #%lu (comm %s path %s): ", | ||
378 | inode->i_sb->s_id, function, inode->i_ino, current->comm, path); | ||
379 | vprintk(fmt, args); | ||
380 | printk("\n"); | ||
381 | va_end(args); | ||
382 | |||
383 | ext4_handle_error(inode->i_sb); | ||
384 | } | ||
385 | |||
350 | static const char *ext4_decode_error(struct super_block *sb, int errno, | 386 | static const char *ext4_decode_error(struct super_block *sb, int errno, |
351 | char nbuf[16]) | 387 | char nbuf[16]) |
352 | { | 388 | { |
@@ -450,7 +486,7 @@ void ext4_msg (struct super_block * sb, const char *prefix, | |||
450 | va_end(args); | 486 | va_end(args); |
451 | } | 487 | } |
452 | 488 | ||
453 | void ext4_warning(struct super_block *sb, const char *function, | 489 | void __ext4_warning(struct super_block *sb, const char *function, |
454 | const char *fmt, ...) | 490 | const char *fmt, ...) |
455 | { | 491 | { |
456 | va_list args; | 492 | va_list args; |
@@ -507,7 +543,7 @@ void ext4_update_dynamic_rev(struct super_block *sb) | |||
507 | if (le32_to_cpu(es->s_rev_level) > EXT4_GOOD_OLD_REV) | 543 | if (le32_to_cpu(es->s_rev_level) > EXT4_GOOD_OLD_REV) |
508 | return; | 544 | return; |
509 | 545 | ||
510 | ext4_warning(sb, __func__, | 546 | ext4_warning(sb, |
511 | "updating to rev %d because of new feature flag, " | 547 | "updating to rev %d because of new feature flag, " |
512 | "running e2fsck is recommended", | 548 | "running e2fsck is recommended", |
513 | EXT4_DYNAMIC_REV); | 549 | EXT4_DYNAMIC_REV); |
@@ -708,7 +744,8 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) | |||
708 | #ifdef CONFIG_QUOTA | 744 | #ifdef CONFIG_QUOTA |
709 | ei->i_reserved_quota = 0; | 745 | ei->i_reserved_quota = 0; |
710 | #endif | 746 | #endif |
711 | INIT_LIST_HEAD(&ei->i_aio_dio_complete_list); | 747 | INIT_LIST_HEAD(&ei->i_completed_io_list); |
748 | spin_lock_init(&ei->i_completed_io_lock); | ||
712 | ei->cur_aio_dio = NULL; | 749 | ei->cur_aio_dio = NULL; |
713 | ei->i_sync_tid = 0; | 750 | ei->i_sync_tid = 0; |
714 | ei->i_datasync_tid = 0; | 751 | ei->i_datasync_tid = 0; |
@@ -761,6 +798,7 @@ static void destroy_inodecache(void) | |||
761 | 798 | ||
762 | static void ext4_clear_inode(struct inode *inode) | 799 | static void ext4_clear_inode(struct inode *inode) |
763 | { | 800 | { |
801 | dquot_drop(inode); | ||
764 | ext4_discard_preallocations(inode); | 802 | ext4_discard_preallocations(inode); |
765 | if (EXT4_JOURNAL(inode)) | 803 | if (EXT4_JOURNAL(inode)) |
766 | jbd2_journal_release_jbd_inode(EXT4_SB(inode->i_sb)->s_journal, | 804 | jbd2_journal_release_jbd_inode(EXT4_SB(inode->i_sb)->s_journal, |
@@ -796,10 +834,10 @@ static inline void ext4_show_quota_options(struct seq_file *seq, | |||
796 | if (sbi->s_qf_names[GRPQUOTA]) | 834 | if (sbi->s_qf_names[GRPQUOTA]) |
797 | seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]); | 835 | seq_printf(seq, ",grpjquota=%s", sbi->s_qf_names[GRPQUOTA]); |
798 | 836 | ||
799 | if (sbi->s_mount_opt & EXT4_MOUNT_USRQUOTA) | 837 | if (test_opt(sb, USRQUOTA)) |
800 | seq_puts(seq, ",usrquota"); | 838 | seq_puts(seq, ",usrquota"); |
801 | 839 | ||
802 | if (sbi->s_mount_opt & EXT4_MOUNT_GRPQUOTA) | 840 | if (test_opt(sb, GRPQUOTA)) |
803 | seq_puts(seq, ",grpquota"); | 841 | seq_puts(seq, ",grpquota"); |
804 | #endif | 842 | #endif |
805 | } | 843 | } |
@@ -926,6 +964,9 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
926 | if (test_opt(sb, NOLOAD)) | 964 | if (test_opt(sb, NOLOAD)) |
927 | seq_puts(seq, ",norecovery"); | 965 | seq_puts(seq, ",norecovery"); |
928 | 966 | ||
967 | if (test_opt(sb, DIOREAD_NOLOCK)) | ||
968 | seq_puts(seq, ",dioread_nolock"); | ||
969 | |||
929 | ext4_show_quota_options(seq, sb); | 970 | ext4_show_quota_options(seq, sb); |
930 | 971 | ||
931 | return 0; | 972 | return 0; |
@@ -1012,19 +1053,9 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type, | |||
1012 | const char *data, size_t len, loff_t off); | 1053 | const char *data, size_t len, loff_t off); |
1013 | 1054 | ||
1014 | static const struct dquot_operations ext4_quota_operations = { | 1055 | static const struct dquot_operations ext4_quota_operations = { |
1015 | .initialize = dquot_initialize, | ||
1016 | .drop = dquot_drop, | ||
1017 | .alloc_space = dquot_alloc_space, | ||
1018 | .reserve_space = dquot_reserve_space, | ||
1019 | .claim_space = dquot_claim_space, | ||
1020 | .release_rsv = dquot_release_reserved_space, | ||
1021 | #ifdef CONFIG_QUOTA | 1056 | #ifdef CONFIG_QUOTA |
1022 | .get_reserved_space = ext4_get_reserved_space, | 1057 | .get_reserved_space = ext4_get_reserved_space, |
1023 | #endif | 1058 | #endif |
1024 | .alloc_inode = dquot_alloc_inode, | ||
1025 | .free_space = dquot_free_space, | ||
1026 | .free_inode = dquot_free_inode, | ||
1027 | .transfer = dquot_transfer, | ||
1028 | .write_dquot = ext4_write_dquot, | 1059 | .write_dquot = ext4_write_dquot, |
1029 | .acquire_dquot = ext4_acquire_dquot, | 1060 | .acquire_dquot = ext4_acquire_dquot, |
1030 | .release_dquot = ext4_release_dquot, | 1061 | .release_dquot = ext4_release_dquot, |
@@ -1109,6 +1140,7 @@ enum { | |||
1109 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, | 1140 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, |
1110 | Opt_block_validity, Opt_noblock_validity, | 1141 | Opt_block_validity, Opt_noblock_validity, |
1111 | Opt_inode_readahead_blks, Opt_journal_ioprio, | 1142 | Opt_inode_readahead_blks, Opt_journal_ioprio, |
1143 | Opt_dioread_nolock, Opt_dioread_lock, | ||
1112 | Opt_discard, Opt_nodiscard, | 1144 | Opt_discard, Opt_nodiscard, |
1113 | }; | 1145 | }; |
1114 | 1146 | ||
@@ -1176,6 +1208,8 @@ static const match_table_t tokens = { | |||
1176 | {Opt_auto_da_alloc, "auto_da_alloc=%u"}, | 1208 | {Opt_auto_da_alloc, "auto_da_alloc=%u"}, |
1177 | {Opt_auto_da_alloc, "auto_da_alloc"}, | 1209 | {Opt_auto_da_alloc, "auto_da_alloc"}, |
1178 | {Opt_noauto_da_alloc, "noauto_da_alloc"}, | 1210 | {Opt_noauto_da_alloc, "noauto_da_alloc"}, |
1211 | {Opt_dioread_nolock, "dioread_nolock"}, | ||
1212 | {Opt_dioread_lock, "dioread_lock"}, | ||
1179 | {Opt_discard, "discard"}, | 1213 | {Opt_discard, "discard"}, |
1180 | {Opt_nodiscard, "nodiscard"}, | 1214 | {Opt_nodiscard, "nodiscard"}, |
1181 | {Opt_err, NULL}, | 1215 | {Opt_err, NULL}, |
@@ -1205,6 +1239,66 @@ static ext4_fsblk_t get_sb_block(void **data) | |||
1205 | } | 1239 | } |
1206 | 1240 | ||
1207 | #define DEFAULT_JOURNAL_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 3)) | 1241 | #define DEFAULT_JOURNAL_IOPRIO (IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 3)) |
1242 | static char deprecated_msg[] = "Mount option \"%s\" will be removed by %s\n" | ||
1243 | "Contact linux-ext4@vger.kernel.org if you think we should keep it.\n"; | ||
1244 | |||
1245 | #ifdef CONFIG_QUOTA | ||
1246 | static int set_qf_name(struct super_block *sb, int qtype, substring_t *args) | ||
1247 | { | ||
1248 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
1249 | char *qname; | ||
1250 | |||
1251 | if (sb_any_quota_loaded(sb) && | ||
1252 | !sbi->s_qf_names[qtype]) { | ||
1253 | ext4_msg(sb, KERN_ERR, | ||
1254 | "Cannot change journaled " | ||
1255 | "quota options when quota turned on"); | ||
1256 | return 0; | ||
1257 | } | ||
1258 | qname = match_strdup(args); | ||
1259 | if (!qname) { | ||
1260 | ext4_msg(sb, KERN_ERR, | ||
1261 | "Not enough memory for storing quotafile name"); | ||
1262 | return 0; | ||
1263 | } | ||
1264 | if (sbi->s_qf_names[qtype] && | ||
1265 | strcmp(sbi->s_qf_names[qtype], qname)) { | ||
1266 | ext4_msg(sb, KERN_ERR, | ||
1267 | "%s quota file already specified", QTYPE2NAME(qtype)); | ||
1268 | kfree(qname); | ||
1269 | return 0; | ||
1270 | } | ||
1271 | sbi->s_qf_names[qtype] = qname; | ||
1272 | if (strchr(sbi->s_qf_names[qtype], '/')) { | ||
1273 | ext4_msg(sb, KERN_ERR, | ||
1274 | "quotafile must be on filesystem root"); | ||
1275 | kfree(sbi->s_qf_names[qtype]); | ||
1276 | sbi->s_qf_names[qtype] = NULL; | ||
1277 | return 0; | ||
1278 | } | ||
1279 | set_opt(sbi->s_mount_opt, QUOTA); | ||
1280 | return 1; | ||
1281 | } | ||
1282 | |||
1283 | static int clear_qf_name(struct super_block *sb, int qtype) | ||
1284 | { | ||
1285 | |||
1286 | struct ext4_sb_info *sbi = EXT4_SB(sb); | ||
1287 | |||
1288 | if (sb_any_quota_loaded(sb) && | ||
1289 | sbi->s_qf_names[qtype]) { | ||
1290 | ext4_msg(sb, KERN_ERR, "Cannot change journaled quota options" | ||
1291 | " when quota turned on"); | ||
1292 | return 0; | ||
1293 | } | ||
1294 | /* | ||
1295 | * The space will be released later when all options are confirmed | ||
1296 | * to be correct | ||
1297 | */ | ||
1298 | sbi->s_qf_names[qtype] = NULL; | ||
1299 | return 1; | ||
1300 | } | ||
1301 | #endif | ||
1208 | 1302 | ||
1209 | static int parse_options(char *options, struct super_block *sb, | 1303 | static int parse_options(char *options, struct super_block *sb, |
1210 | unsigned long *journal_devnum, | 1304 | unsigned long *journal_devnum, |
@@ -1217,8 +1311,7 @@ static int parse_options(char *options, struct super_block *sb, | |||
1217 | int data_opt = 0; | 1311 | int data_opt = 0; |
1218 | int option; | 1312 | int option; |
1219 | #ifdef CONFIG_QUOTA | 1313 | #ifdef CONFIG_QUOTA |
1220 | int qtype, qfmt; | 1314 | int qfmt; |
1221 | char *qname; | ||
1222 | #endif | 1315 | #endif |
1223 | 1316 | ||
1224 | if (!options) | 1317 | if (!options) |
@@ -1229,19 +1322,31 @@ static int parse_options(char *options, struct super_block *sb, | |||
1229 | if (!*p) | 1322 | if (!*p) |
1230 | continue; | 1323 | continue; |
1231 | 1324 | ||
1325 | /* | ||
1326 | * Initialize args struct so we know whether arg was | ||
1327 | * found; some options take optional arguments. | ||
1328 | */ | ||
1329 | args[0].to = args[0].from = 0; | ||
1232 | token = match_token(p, tokens, args); | 1330 | token = match_token(p, tokens, args); |
1233 | switch (token) { | 1331 | switch (token) { |
1234 | case Opt_bsd_df: | 1332 | case Opt_bsd_df: |
1333 | ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38"); | ||
1235 | clear_opt(sbi->s_mount_opt, MINIX_DF); | 1334 | clear_opt(sbi->s_mount_opt, MINIX_DF); |
1236 | break; | 1335 | break; |
1237 | case Opt_minix_df: | 1336 | case Opt_minix_df: |
1337 | ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38"); | ||
1238 | set_opt(sbi->s_mount_opt, MINIX_DF); | 1338 | set_opt(sbi->s_mount_opt, MINIX_DF); |
1339 | |||
1239 | break; | 1340 | break; |
1240 | case Opt_grpid: | 1341 | case Opt_grpid: |
1342 | ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38"); | ||
1241 | set_opt(sbi->s_mount_opt, GRPID); | 1343 | set_opt(sbi->s_mount_opt, GRPID); |
1344 | |||
1242 | break; | 1345 | break; |
1243 | case Opt_nogrpid: | 1346 | case Opt_nogrpid: |
1347 | ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38"); | ||
1244 | clear_opt(sbi->s_mount_opt, GRPID); | 1348 | clear_opt(sbi->s_mount_opt, GRPID); |
1349 | |||
1245 | break; | 1350 | break; |
1246 | case Opt_resuid: | 1351 | case Opt_resuid: |
1247 | if (match_int(&args[0], &option)) | 1352 | if (match_int(&args[0], &option)) |
@@ -1378,14 +1483,13 @@ static int parse_options(char *options, struct super_block *sb, | |||
1378 | data_opt = EXT4_MOUNT_WRITEBACK_DATA; | 1483 | data_opt = EXT4_MOUNT_WRITEBACK_DATA; |
1379 | datacheck: | 1484 | datacheck: |
1380 | if (is_remount) { | 1485 | if (is_remount) { |
1381 | if ((sbi->s_mount_opt & EXT4_MOUNT_DATA_FLAGS) | 1486 | if (test_opt(sb, DATA_FLAGS) != data_opt) { |
1382 | != data_opt) { | ||
1383 | ext4_msg(sb, KERN_ERR, | 1487 | ext4_msg(sb, KERN_ERR, |
1384 | "Cannot change data mode on remount"); | 1488 | "Cannot change data mode on remount"); |
1385 | return 0; | 1489 | return 0; |
1386 | } | 1490 | } |
1387 | } else { | 1491 | } else { |
1388 | sbi->s_mount_opt &= ~EXT4_MOUNT_DATA_FLAGS; | 1492 | clear_opt(sbi->s_mount_opt, DATA_FLAGS); |
1389 | sbi->s_mount_opt |= data_opt; | 1493 | sbi->s_mount_opt |= data_opt; |
1390 | } | 1494 | } |
1391 | break; | 1495 | break; |
@@ -1397,63 +1501,22 @@ static int parse_options(char *options, struct super_block *sb, | |||
1397 | break; | 1501 | break; |
1398 | #ifdef CONFIG_QUOTA | 1502 | #ifdef CONFIG_QUOTA |
1399 | case Opt_usrjquota: | 1503 | case Opt_usrjquota: |
1400 | qtype = USRQUOTA; | 1504 | if (!set_qf_name(sb, USRQUOTA, &args[0])) |
1401 | goto set_qf_name; | ||
1402 | case Opt_grpjquota: | ||
1403 | qtype = GRPQUOTA; | ||
1404 | set_qf_name: | ||
1405 | if (sb_any_quota_loaded(sb) && | ||
1406 | !sbi->s_qf_names[qtype]) { | ||
1407 | ext4_msg(sb, KERN_ERR, | ||
1408 | "Cannot change journaled " | ||
1409 | "quota options when quota turned on"); | ||
1410 | return 0; | 1505 | return 0; |
1411 | } | 1506 | break; |
1412 | qname = match_strdup(&args[0]); | 1507 | case Opt_grpjquota: |
1413 | if (!qname) { | 1508 | if (!set_qf_name(sb, GRPQUOTA, &args[0])) |
1414 | ext4_msg(sb, KERN_ERR, | ||
1415 | "Not enough memory for " | ||
1416 | "storing quotafile name"); | ||
1417 | return 0; | ||
1418 | } | ||
1419 | if (sbi->s_qf_names[qtype] && | ||
1420 | strcmp(sbi->s_qf_names[qtype], qname)) { | ||
1421 | ext4_msg(sb, KERN_ERR, | ||
1422 | "%s quota file already " | ||
1423 | "specified", QTYPE2NAME(qtype)); | ||
1424 | kfree(qname); | ||
1425 | return 0; | ||
1426 | } | ||
1427 | sbi->s_qf_names[qtype] = qname; | ||
1428 | if (strchr(sbi->s_qf_names[qtype], '/')) { | ||
1429 | ext4_msg(sb, KERN_ERR, | ||
1430 | "quotafile must be on " | ||
1431 | "filesystem root"); | ||
1432 | kfree(sbi->s_qf_names[qtype]); | ||
1433 | sbi->s_qf_names[qtype] = NULL; | ||
1434 | return 0; | 1509 | return 0; |
1435 | } | ||
1436 | set_opt(sbi->s_mount_opt, QUOTA); | ||
1437 | break; | 1510 | break; |
1438 | case Opt_offusrjquota: | 1511 | case Opt_offusrjquota: |
1439 | qtype = USRQUOTA; | 1512 | if (!clear_qf_name(sb, USRQUOTA)) |
1440 | goto clear_qf_name; | 1513 | return 0; |
1514 | break; | ||
1441 | case Opt_offgrpjquota: | 1515 | case Opt_offgrpjquota: |
1442 | qtype = GRPQUOTA; | 1516 | if (!clear_qf_name(sb, GRPQUOTA)) |
1443 | clear_qf_name: | ||
1444 | if (sb_any_quota_loaded(sb) && | ||
1445 | sbi->s_qf_names[qtype]) { | ||
1446 | ext4_msg(sb, KERN_ERR, "Cannot change " | ||
1447 | "journaled quota options when " | ||
1448 | "quota turned on"); | ||
1449 | return 0; | 1517 | return 0; |
1450 | } | ||
1451 | /* | ||
1452 | * The space will be released later when all options | ||
1453 | * are confirmed to be correct | ||
1454 | */ | ||
1455 | sbi->s_qf_names[qtype] = NULL; | ||
1456 | break; | 1518 | break; |
1519 | |||
1457 | case Opt_jqfmt_vfsold: | 1520 | case Opt_jqfmt_vfsold: |
1458 | qfmt = QFMT_VFS_OLD; | 1521 | qfmt = QFMT_VFS_OLD; |
1459 | goto set_qf_format; | 1522 | goto set_qf_format; |
@@ -1518,10 +1581,11 @@ set_qf_format: | |||
1518 | clear_opt(sbi->s_mount_opt, BARRIER); | 1581 | clear_opt(sbi->s_mount_opt, BARRIER); |
1519 | break; | 1582 | break; |
1520 | case Opt_barrier: | 1583 | case Opt_barrier: |
1521 | if (match_int(&args[0], &option)) { | 1584 | if (args[0].from) { |
1522 | set_opt(sbi->s_mount_opt, BARRIER); | 1585 | if (match_int(&args[0], &option)) |
1523 | break; | 1586 | return 0; |
1524 | } | 1587 | } else |
1588 | option = 1; /* No argument, default to 1 */ | ||
1525 | if (option) | 1589 | if (option) |
1526 | set_opt(sbi->s_mount_opt, BARRIER); | 1590 | set_opt(sbi->s_mount_opt, BARRIER); |
1527 | else | 1591 | else |
@@ -1594,10 +1658,11 @@ set_qf_format: | |||
1594 | set_opt(sbi->s_mount_opt,NO_AUTO_DA_ALLOC); | 1658 | set_opt(sbi->s_mount_opt,NO_AUTO_DA_ALLOC); |
1595 | break; | 1659 | break; |
1596 | case Opt_auto_da_alloc: | 1660 | case Opt_auto_da_alloc: |
1597 | if (match_int(&args[0], &option)) { | 1661 | if (args[0].from) { |
1598 | clear_opt(sbi->s_mount_opt, NO_AUTO_DA_ALLOC); | 1662 | if (match_int(&args[0], &option)) |
1599 | break; | 1663 | return 0; |
1600 | } | 1664 | } else |
1665 | option = 1; /* No argument, default to 1 */ | ||
1601 | if (option) | 1666 | if (option) |
1602 | clear_opt(sbi->s_mount_opt, NO_AUTO_DA_ALLOC); | 1667 | clear_opt(sbi->s_mount_opt, NO_AUTO_DA_ALLOC); |
1603 | else | 1668 | else |
@@ -1609,6 +1674,12 @@ set_qf_format: | |||
1609 | case Opt_nodiscard: | 1674 | case Opt_nodiscard: |
1610 | clear_opt(sbi->s_mount_opt, DISCARD); | 1675 | clear_opt(sbi->s_mount_opt, DISCARD); |
1611 | break; | 1676 | break; |
1677 | case Opt_dioread_nolock: | ||
1678 | set_opt(sbi->s_mount_opt, DIOREAD_NOLOCK); | ||
1679 | break; | ||
1680 | case Opt_dioread_lock: | ||
1681 | clear_opt(sbi->s_mount_opt, DIOREAD_NOLOCK); | ||
1682 | break; | ||
1612 | default: | 1683 | default: |
1613 | ext4_msg(sb, KERN_ERR, | 1684 | ext4_msg(sb, KERN_ERR, |
1614 | "Unrecognized mount option \"%s\" " | 1685 | "Unrecognized mount option \"%s\" " |
@@ -1618,18 +1689,13 @@ set_qf_format: | |||
1618 | } | 1689 | } |
1619 | #ifdef CONFIG_QUOTA | 1690 | #ifdef CONFIG_QUOTA |
1620 | if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) { | 1691 | if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) { |
1621 | if ((sbi->s_mount_opt & EXT4_MOUNT_USRQUOTA) && | 1692 | if (test_opt(sb, USRQUOTA) && sbi->s_qf_names[USRQUOTA]) |
1622 | sbi->s_qf_names[USRQUOTA]) | ||
1623 | clear_opt(sbi->s_mount_opt, USRQUOTA); | 1693 | clear_opt(sbi->s_mount_opt, USRQUOTA); |
1624 | 1694 | ||
1625 | if ((sbi->s_mount_opt & EXT4_MOUNT_GRPQUOTA) && | 1695 | if (test_opt(sb, GRPQUOTA) && sbi->s_qf_names[GRPQUOTA]) |
1626 | sbi->s_qf_names[GRPQUOTA]) | ||
1627 | clear_opt(sbi->s_mount_opt, GRPQUOTA); | 1696 | clear_opt(sbi->s_mount_opt, GRPQUOTA); |
1628 | 1697 | ||
1629 | if ((sbi->s_qf_names[USRQUOTA] && | 1698 | if (test_opt(sb, GRPQUOTA) || test_opt(sb, USRQUOTA)) { |
1630 | (sbi->s_mount_opt & EXT4_MOUNT_GRPQUOTA)) || | ||
1631 | (sbi->s_qf_names[GRPQUOTA] && | ||
1632 | (sbi->s_mount_opt & EXT4_MOUNT_USRQUOTA))) { | ||
1633 | ext4_msg(sb, KERN_ERR, "old and new quota " | 1699 | ext4_msg(sb, KERN_ERR, "old and new quota " |
1634 | "format mixing"); | 1700 | "format mixing"); |
1635 | return 0; | 1701 | return 0; |
@@ -1939,7 +2005,7 @@ static void ext4_orphan_cleanup(struct super_block *sb, | |||
1939 | } | 2005 | } |
1940 | 2006 | ||
1941 | list_add(&EXT4_I(inode)->i_orphan, &EXT4_SB(sb)->s_orphan); | 2007 | list_add(&EXT4_I(inode)->i_orphan, &EXT4_SB(sb)->s_orphan); |
1942 | vfs_dq_init(inode); | 2008 | dquot_initialize(inode); |
1943 | if (inode->i_nlink) { | 2009 | if (inode->i_nlink) { |
1944 | ext4_msg(sb, KERN_DEBUG, | 2010 | ext4_msg(sb, KERN_DEBUG, |
1945 | "%s: truncating inode %lu to %lld bytes", | 2011 | "%s: truncating inode %lu to %lld bytes", |
@@ -2292,7 +2358,7 @@ static void ext4_sb_release(struct kobject *kobj) | |||
2292 | } | 2358 | } |
2293 | 2359 | ||
2294 | 2360 | ||
2295 | static struct sysfs_ops ext4_attr_ops = { | 2361 | static const struct sysfs_ops ext4_attr_ops = { |
2296 | .show = ext4_attr_show, | 2362 | .show = ext4_attr_show, |
2297 | .store = ext4_attr_store, | 2363 | .store = ext4_attr_store, |
2298 | }; | 2364 | }; |
@@ -2432,8 +2498,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2432 | def_mount_opts = le32_to_cpu(es->s_default_mount_opts); | 2498 | def_mount_opts = le32_to_cpu(es->s_default_mount_opts); |
2433 | if (def_mount_opts & EXT4_DEFM_DEBUG) | 2499 | if (def_mount_opts & EXT4_DEFM_DEBUG) |
2434 | set_opt(sbi->s_mount_opt, DEBUG); | 2500 | set_opt(sbi->s_mount_opt, DEBUG); |
2435 | if (def_mount_opts & EXT4_DEFM_BSDGROUPS) | 2501 | if (def_mount_opts & EXT4_DEFM_BSDGROUPS) { |
2502 | ext4_msg(sb, KERN_WARNING, deprecated_msg, "bsdgroups", | ||
2503 | "2.6.38"); | ||
2436 | set_opt(sbi->s_mount_opt, GRPID); | 2504 | set_opt(sbi->s_mount_opt, GRPID); |
2505 | } | ||
2437 | if (def_mount_opts & EXT4_DEFM_UID16) | 2506 | if (def_mount_opts & EXT4_DEFM_UID16) |
2438 | set_opt(sbi->s_mount_opt, NO_UID32); | 2507 | set_opt(sbi->s_mount_opt, NO_UID32); |
2439 | #ifdef CONFIG_EXT4_FS_XATTR | 2508 | #ifdef CONFIG_EXT4_FS_XATTR |
@@ -2445,11 +2514,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2445 | set_opt(sbi->s_mount_opt, POSIX_ACL); | 2514 | set_opt(sbi->s_mount_opt, POSIX_ACL); |
2446 | #endif | 2515 | #endif |
2447 | if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_DATA) | 2516 | if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_DATA) |
2448 | sbi->s_mount_opt |= EXT4_MOUNT_JOURNAL_DATA; | 2517 | set_opt(sbi->s_mount_opt, JOURNAL_DATA); |
2449 | else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_ORDERED) | 2518 | else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_ORDERED) |
2450 | sbi->s_mount_opt |= EXT4_MOUNT_ORDERED_DATA; | 2519 | set_opt(sbi->s_mount_opt, ORDERED_DATA); |
2451 | else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_WBACK) | 2520 | else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_WBACK) |
2452 | sbi->s_mount_opt |= EXT4_MOUNT_WRITEBACK_DATA; | 2521 | set_opt(sbi->s_mount_opt, WRITEBACK_DATA); |
2453 | 2522 | ||
2454 | if (le16_to_cpu(sbi->s_es->s_errors) == EXT4_ERRORS_PANIC) | 2523 | if (le16_to_cpu(sbi->s_es->s_errors) == EXT4_ERRORS_PANIC) |
2455 | set_opt(sbi->s_mount_opt, ERRORS_PANIC); | 2524 | set_opt(sbi->s_mount_opt, ERRORS_PANIC); |
@@ -2477,7 +2546,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2477 | goto failed_mount; | 2546 | goto failed_mount; |
2478 | 2547 | ||
2479 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | | 2548 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | |
2480 | ((sbi->s_mount_opt & EXT4_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); | 2549 | (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); |
2481 | 2550 | ||
2482 | if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV && | 2551 | if (le32_to_cpu(es->s_rev_level) == EXT4_GOOD_OLD_REV && |
2483 | (EXT4_HAS_COMPAT_FEATURE(sb, ~0U) || | 2552 | (EXT4_HAS_COMPAT_FEATURE(sb, ~0U) || |
@@ -2766,7 +2835,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2766 | EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) { | 2835 | EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_RECOVER)) { |
2767 | ext4_msg(sb, KERN_ERR, "required journal recovery " | 2836 | ext4_msg(sb, KERN_ERR, "required journal recovery " |
2768 | "suppressed and not mounted read-only"); | 2837 | "suppressed and not mounted read-only"); |
2769 | goto failed_mount4; | 2838 | goto failed_mount_wq; |
2770 | } else { | 2839 | } else { |
2771 | clear_opt(sbi->s_mount_opt, DATA_FLAGS); | 2840 | clear_opt(sbi->s_mount_opt, DATA_FLAGS); |
2772 | set_opt(sbi->s_mount_opt, WRITEBACK_DATA); | 2841 | set_opt(sbi->s_mount_opt, WRITEBACK_DATA); |
@@ -2779,7 +2848,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2779 | !jbd2_journal_set_features(EXT4_SB(sb)->s_journal, 0, 0, | 2848 | !jbd2_journal_set_features(EXT4_SB(sb)->s_journal, 0, 0, |
2780 | JBD2_FEATURE_INCOMPAT_64BIT)) { | 2849 | JBD2_FEATURE_INCOMPAT_64BIT)) { |
2781 | ext4_msg(sb, KERN_ERR, "Failed to set 64-bit journal feature"); | 2850 | ext4_msg(sb, KERN_ERR, "Failed to set 64-bit journal feature"); |
2782 | goto failed_mount4; | 2851 | goto failed_mount_wq; |
2783 | } | 2852 | } |
2784 | 2853 | ||
2785 | if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) { | 2854 | if (test_opt(sb, JOURNAL_ASYNC_COMMIT)) { |
@@ -2818,7 +2887,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2818 | (sbi->s_journal, 0, 0, JBD2_FEATURE_INCOMPAT_REVOKE)) { | 2887 | (sbi->s_journal, 0, 0, JBD2_FEATURE_INCOMPAT_REVOKE)) { |
2819 | ext4_msg(sb, KERN_ERR, "Journal does not support " | 2888 | ext4_msg(sb, KERN_ERR, "Journal does not support " |
2820 | "requested data journaling mode"); | 2889 | "requested data journaling mode"); |
2821 | goto failed_mount4; | 2890 | goto failed_mount_wq; |
2822 | } | 2891 | } |
2823 | default: | 2892 | default: |
2824 | break; | 2893 | break; |
@@ -2826,13 +2895,17 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
2826 | set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); | 2895 | set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); |
2827 | 2896 | ||
2828 | no_journal: | 2897 | no_journal: |
2829 | |||
2830 | if (test_opt(sb, NOBH)) { | 2898 | if (test_opt(sb, NOBH)) { |
2831 | if (!(test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)) { | 2899 | if (!(test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_WRITEBACK_DATA)) { |
2832 | ext4_msg(sb, KERN_WARNING, "Ignoring nobh option - " | 2900 | ext4_msg(sb, KERN_WARNING, "Ignoring nobh option - " |
2833 | "its supported only with writeback mode"); | 2901 | "its supported only with writeback mode"); |
2834 | clear_opt(sbi->s_mount_opt, NOBH); | 2902 | clear_opt(sbi->s_mount_opt, NOBH); |
2835 | } | 2903 | } |
2904 | if (test_opt(sb, DIOREAD_NOLOCK)) { | ||
2905 | ext4_msg(sb, KERN_WARNING, "dioread_nolock option is " | ||
2906 | "not supported with nobh mode"); | ||
2907 | goto failed_mount_wq; | ||
2908 | } | ||
2836 | } | 2909 | } |
2837 | EXT4_SB(sb)->dio_unwritten_wq = create_workqueue("ext4-dio-unwritten"); | 2910 | EXT4_SB(sb)->dio_unwritten_wq = create_workqueue("ext4-dio-unwritten"); |
2838 | if (!EXT4_SB(sb)->dio_unwritten_wq) { | 2911 | if (!EXT4_SB(sb)->dio_unwritten_wq) { |
@@ -2897,6 +2970,18 @@ no_journal: | |||
2897 | "requested data journaling mode"); | 2970 | "requested data journaling mode"); |
2898 | clear_opt(sbi->s_mount_opt, DELALLOC); | 2971 | clear_opt(sbi->s_mount_opt, DELALLOC); |
2899 | } | 2972 | } |
2973 | if (test_opt(sb, DIOREAD_NOLOCK)) { | ||
2974 | if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { | ||
2975 | ext4_msg(sb, KERN_WARNING, "Ignoring dioread_nolock " | ||
2976 | "option - requested data journaling mode"); | ||
2977 | clear_opt(sbi->s_mount_opt, DIOREAD_NOLOCK); | ||
2978 | } | ||
2979 | if (sb->s_blocksize < PAGE_SIZE) { | ||
2980 | ext4_msg(sb, KERN_WARNING, "Ignoring dioread_nolock " | ||
2981 | "option - block size is too small"); | ||
2982 | clear_opt(sbi->s_mount_opt, DIOREAD_NOLOCK); | ||
2983 | } | ||
2984 | } | ||
2900 | 2985 | ||
2901 | err = ext4_setup_system_zone(sb); | 2986 | err = ext4_setup_system_zone(sb); |
2902 | if (err) { | 2987 | if (err) { |
@@ -3360,10 +3445,9 @@ static void ext4_clear_journal_err(struct super_block *sb, | |||
3360 | char nbuf[16]; | 3445 | char nbuf[16]; |
3361 | 3446 | ||
3362 | errstr = ext4_decode_error(sb, j_errno, nbuf); | 3447 | errstr = ext4_decode_error(sb, j_errno, nbuf); |
3363 | ext4_warning(sb, __func__, "Filesystem error recorded " | 3448 | ext4_warning(sb, "Filesystem error recorded " |
3364 | "from previous mount: %s", errstr); | 3449 | "from previous mount: %s", errstr); |
3365 | ext4_warning(sb, __func__, "Marking fs in need of " | 3450 | ext4_warning(sb, "Marking fs in need of filesystem check."); |
3366 | "filesystem check."); | ||
3367 | 3451 | ||
3368 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; | 3452 | EXT4_SB(sb)->s_mount_state |= EXT4_ERROR_FS; |
3369 | es->s_state |= cpu_to_le16(EXT4_ERROR_FS); | 3453 | es->s_state |= cpu_to_le16(EXT4_ERROR_FS); |
@@ -3514,7 +3598,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) | |||
3514 | ext4_abort(sb, __func__, "Abort forced by user"); | 3598 | ext4_abort(sb, __func__, "Abort forced by user"); |
3515 | 3599 | ||
3516 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | | 3600 | sb->s_flags = (sb->s_flags & ~MS_POSIXACL) | |
3517 | ((sbi->s_mount_opt & EXT4_MOUNT_POSIX_ACL) ? MS_POSIXACL : 0); | 3601 | (test_opt(sb, POSIX_ACL) ? MS_POSIXACL : 0); |
3518 | 3602 | ||
3519 | es = sbi->s_es; | 3603 | es = sbi->s_es; |
3520 | 3604 | ||
@@ -3708,7 +3792,7 @@ static int ext4_statfs(struct dentry *dentry, struct kstatfs *buf) | |||
3708 | * Process 1 Process 2 | 3792 | * Process 1 Process 2 |
3709 | * ext4_create() quota_sync() | 3793 | * ext4_create() quota_sync() |
3710 | * jbd2_journal_start() write_dquot() | 3794 | * jbd2_journal_start() write_dquot() |
3711 | * vfs_dq_init() down(dqio_mutex) | 3795 | * dquot_initialize() down(dqio_mutex) |
3712 | * down(dqio_mutex) jbd2_journal_start() | 3796 | * down(dqio_mutex) jbd2_journal_start() |
3713 | * | 3797 | * |
3714 | */ | 3798 | */ |
@@ -3917,9 +4001,7 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type, | |||
3917 | ext4_lblk_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb); | 4001 | ext4_lblk_t blk = off >> EXT4_BLOCK_SIZE_BITS(sb); |
3918 | int err = 0; | 4002 | int err = 0; |
3919 | int offset = off & (sb->s_blocksize - 1); | 4003 | int offset = off & (sb->s_blocksize - 1); |
3920 | int tocopy; | ||
3921 | int journal_quota = EXT4_SB(sb)->s_qf_names[type] != NULL; | 4004 | int journal_quota = EXT4_SB(sb)->s_qf_names[type] != NULL; |
3922 | size_t towrite = len; | ||
3923 | struct buffer_head *bh; | 4005 | struct buffer_head *bh; |
3924 | handle_t *handle = journal_current_handle(); | 4006 | handle_t *handle = journal_current_handle(); |
3925 | 4007 | ||
@@ -3929,52 +4011,53 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type, | |||
3929 | (unsigned long long)off, (unsigned long long)len); | 4011 | (unsigned long long)off, (unsigned long long)len); |
3930 | return -EIO; | 4012 | return -EIO; |
3931 | } | 4013 | } |
4014 | /* | ||
4015 | * Since we account only one data block in transaction credits, | ||
4016 | * then it is impossible to cross a block boundary. | ||
4017 | */ | ||
4018 | if (sb->s_blocksize - offset < len) { | ||
4019 | ext4_msg(sb, KERN_WARNING, "Quota write (off=%llu, len=%llu)" | ||
4020 | " cancelled because not block aligned", | ||
4021 | (unsigned long long)off, (unsigned long long)len); | ||
4022 | return -EIO; | ||
4023 | } | ||
4024 | |||
3932 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); | 4025 | mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA); |
3933 | while (towrite > 0) { | 4026 | bh = ext4_bread(handle, inode, blk, 1, &err); |
3934 | tocopy = sb->s_blocksize - offset < towrite ? | 4027 | if (!bh) |
3935 | sb->s_blocksize - offset : towrite; | 4028 | goto out; |
3936 | bh = ext4_bread(handle, inode, blk, 1, &err); | 4029 | if (journal_quota) { |
3937 | if (!bh) | 4030 | err = ext4_journal_get_write_access(handle, bh); |
4031 | if (err) { | ||
4032 | brelse(bh); | ||
3938 | goto out; | 4033 | goto out; |
3939 | if (journal_quota) { | ||
3940 | err = ext4_journal_get_write_access(handle, bh); | ||
3941 | if (err) { | ||
3942 | brelse(bh); | ||
3943 | goto out; | ||
3944 | } | ||
3945 | } | 4034 | } |
3946 | lock_buffer(bh); | ||
3947 | memcpy(bh->b_data+offset, data, tocopy); | ||
3948 | flush_dcache_page(bh->b_page); | ||
3949 | unlock_buffer(bh); | ||
3950 | if (journal_quota) | ||
3951 | err = ext4_handle_dirty_metadata(handle, NULL, bh); | ||
3952 | else { | ||
3953 | /* Always do at least ordered writes for quotas */ | ||
3954 | err = ext4_jbd2_file_inode(handle, inode); | ||
3955 | mark_buffer_dirty(bh); | ||
3956 | } | ||
3957 | brelse(bh); | ||
3958 | if (err) | ||
3959 | goto out; | ||
3960 | offset = 0; | ||
3961 | towrite -= tocopy; | ||
3962 | data += tocopy; | ||
3963 | blk++; | ||
3964 | } | 4035 | } |
4036 | lock_buffer(bh); | ||
4037 | memcpy(bh->b_data+offset, data, len); | ||
4038 | flush_dcache_page(bh->b_page); | ||
4039 | unlock_buffer(bh); | ||
4040 | if (journal_quota) | ||
4041 | err = ext4_handle_dirty_metadata(handle, NULL, bh); | ||
4042 | else { | ||
4043 | /* Always do at least ordered writes for quotas */ | ||
4044 | err = ext4_jbd2_file_inode(handle, inode); | ||
4045 | mark_buffer_dirty(bh); | ||
4046 | } | ||
4047 | brelse(bh); | ||
3965 | out: | 4048 | out: |
3966 | if (len == towrite) { | 4049 | if (err) { |
3967 | mutex_unlock(&inode->i_mutex); | 4050 | mutex_unlock(&inode->i_mutex); |
3968 | return err; | 4051 | return err; |
3969 | } | 4052 | } |
3970 | if (inode->i_size < off+len-towrite) { | 4053 | if (inode->i_size < off + len) { |
3971 | i_size_write(inode, off+len-towrite); | 4054 | i_size_write(inode, off + len); |
3972 | EXT4_I(inode)->i_disksize = inode->i_size; | 4055 | EXT4_I(inode)->i_disksize = inode->i_size; |
3973 | } | 4056 | } |
3974 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 4057 | inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
3975 | ext4_mark_inode_dirty(handle, inode); | 4058 | ext4_mark_inode_dirty(handle, inode); |
3976 | mutex_unlock(&inode->i_mutex); | 4059 | mutex_unlock(&inode->i_mutex); |
3977 | return len - towrite; | 4060 | return len; |
3978 | } | 4061 | } |
3979 | 4062 | ||
3980 | #endif | 4063 | #endif |