Commit 1907131bbeabb33db313bad34f3ec1a5faedbd64
Committed by
Jan Kara
1 parent
c06bcbfa1e
Exists in
master
and in
7 other branches
dquot: Detect partial write error to quota file in write_blk() and add printk_ra…
…telimit for quota error messages This patch changes quota_tree.c:write_blk() to detect error caused by partial write to quota file and add a macro to limit control printed quota error messages so we won't fill up dmesg with a corrupted quota file. Signed-off-by: Jiaying Zhang <jiayingz@google.com> Signed-off-by: Jan Kara <jack@suse.cz>
Showing 3 changed files with 36 additions and 22 deletions Side-by-side Diff
fs/quota/quota_tree.c
... | ... | @@ -60,9 +60,17 @@ |
60 | 60 | static ssize_t write_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf) |
61 | 61 | { |
62 | 62 | struct super_block *sb = info->dqi_sb; |
63 | + ssize_t ret; | |
63 | 64 | |
64 | - return sb->s_op->quota_write(sb, info->dqi_type, buf, | |
65 | + ret = sb->s_op->quota_write(sb, info->dqi_type, buf, | |
65 | 66 | info->dqi_usable_bs, blk << info->dqi_blocksize_bits); |
67 | + if (ret != info->dqi_usable_bs) { | |
68 | + q_warn(KERN_WARNING "VFS: dquota write failed on " | |
69 | + "dev %s\n", sb->s_id); | |
70 | + if (ret >= 0) | |
71 | + ret = -EIO; | |
72 | + } | |
73 | + return ret; | |
66 | 74 | } |
67 | 75 | |
68 | 76 | /* Remove empty block from list and return it */ |
... | ... | @@ -152,7 +160,7 @@ |
152 | 160 | dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0); |
153 | 161 | /* No matter whether write succeeds block is out of list */ |
154 | 162 | if (write_blk(info, blk, buf) < 0) |
155 | - printk(KERN_ERR | |
163 | + q_warn(KERN_ERR | |
156 | 164 | "VFS: Can't write block (%u) with free entries.\n", |
157 | 165 | blk); |
158 | 166 | return 0; |
... | ... | @@ -244,7 +252,7 @@ |
244 | 252 | if (le16_to_cpu(dh->dqdh_entries) + 1 >= qtree_dqstr_in_blk(info)) { |
245 | 253 | *err = remove_free_dqentry(info, buf, blk); |
246 | 254 | if (*err < 0) { |
247 | - printk(KERN_ERR "VFS: find_free_dqentry(): Can't " | |
255 | + q_warn(KERN_ERR "VFS: find_free_dqentry(): Can't " | |
248 | 256 | "remove block (%u) from entry free list.\n", |
249 | 257 | blk); |
250 | 258 | goto out_buf; |
... | ... | @@ -268,7 +276,7 @@ |
268 | 276 | #endif |
269 | 277 | *err = write_blk(info, blk, buf); |
270 | 278 | if (*err < 0) { |
271 | - printk(KERN_ERR "VFS: find_free_dqentry(): Can't write quota " | |
279 | + q_warn(KERN_ERR "VFS: find_free_dqentry(): Can't write quota " | |
272 | 280 | "data block %u.\n", blk); |
273 | 281 | goto out_buf; |
274 | 282 | } |
... | ... | @@ -303,7 +311,7 @@ |
303 | 311 | } else { |
304 | 312 | ret = read_blk(info, *treeblk, buf); |
305 | 313 | if (ret < 0) { |
306 | - printk(KERN_ERR "VFS: Can't read tree quota block " | |
314 | + q_warn(KERN_ERR "VFS: Can't read tree quota block " | |
307 | 315 | "%u.\n", *treeblk); |
308 | 316 | goto out_buf; |
309 | 317 | } |
... | ... | @@ -365,7 +373,7 @@ |
365 | 373 | if (!dquot->dq_off) { |
366 | 374 | ret = dq_insert_tree(info, dquot); |
367 | 375 | if (ret < 0) { |
368 | - printk(KERN_ERR "VFS: Error %zd occurred while " | |
376 | + q_warn(KERN_ERR "VFS: Error %zd occurred while " | |
369 | 377 | "creating quota.\n", ret); |
370 | 378 | kfree(ddquot); |
371 | 379 | return ret; |
... | ... | @@ -377,7 +385,7 @@ |
377 | 385 | ret = sb->s_op->quota_write(sb, type, ddquot, info->dqi_entry_size, |
378 | 386 | dquot->dq_off); |
379 | 387 | if (ret != info->dqi_entry_size) { |
380 | - printk(KERN_WARNING "VFS: dquota write failed on dev %s\n", | |
388 | + q_warn(KERN_WARNING "VFS: dquota write failed on dev %s\n", | |
381 | 389 | sb->s_id); |
382 | 390 | if (ret >= 0) |
383 | 391 | ret = -ENOSPC; |
384 | 392 | |
... | ... | @@ -402,14 +410,14 @@ |
402 | 410 | if (!buf) |
403 | 411 | return -ENOMEM; |
404 | 412 | if (dquot->dq_off >> info->dqi_blocksize_bits != blk) { |
405 | - printk(KERN_ERR "VFS: Quota structure has offset to other " | |
413 | + q_warn(KERN_ERR "VFS: Quota structure has offset to other " | |
406 | 414 | "block (%u) than it should (%u).\n", blk, |
407 | 415 | (uint)(dquot->dq_off >> info->dqi_blocksize_bits)); |
408 | 416 | goto out_buf; |
409 | 417 | } |
410 | 418 | ret = read_blk(info, blk, buf); |
411 | 419 | if (ret < 0) { |
412 | - printk(KERN_ERR "VFS: Can't read quota data block %u\n", blk); | |
420 | + q_warn(KERN_ERR "VFS: Can't read quota data block %u\n", blk); | |
413 | 421 | goto out_buf; |
414 | 422 | } |
415 | 423 | dh = (struct qt_disk_dqdbheader *)buf; |
... | ... | @@ -419,7 +427,7 @@ |
419 | 427 | if (ret >= 0) |
420 | 428 | ret = put_free_dqblk(info, buf, blk); |
421 | 429 | if (ret < 0) { |
422 | - printk(KERN_ERR "VFS: Can't move quota data block (%u) " | |
430 | + q_warn(KERN_ERR "VFS: Can't move quota data block (%u) " | |
423 | 431 | "to free list.\n", blk); |
424 | 432 | goto out_buf; |
425 | 433 | } |
426 | 434 | |
... | ... | @@ -432,14 +440,14 @@ |
432 | 440 | /* Insert will write block itself */ |
433 | 441 | ret = insert_free_dqentry(info, buf, blk); |
434 | 442 | if (ret < 0) { |
435 | - printk(KERN_ERR "VFS: Can't insert quota data " | |
443 | + q_warn(KERN_ERR "VFS: Can't insert quota data " | |
436 | 444 | "block (%u) to free entry list.\n", blk); |
437 | 445 | goto out_buf; |
438 | 446 | } |
439 | 447 | } else { |
440 | 448 | ret = write_blk(info, blk, buf); |
441 | 449 | if (ret < 0) { |
442 | - printk(KERN_ERR "VFS: Can't write quota data " | |
450 | + q_warn(KERN_ERR "VFS: Can't write quota data " | |
443 | 451 | "block %u\n", blk); |
444 | 452 | goto out_buf; |
445 | 453 | } |
... | ... | @@ -464,7 +472,7 @@ |
464 | 472 | return -ENOMEM; |
465 | 473 | ret = read_blk(info, *blk, buf); |
466 | 474 | if (ret < 0) { |
467 | - printk(KERN_ERR "VFS: Can't read quota data block %u\n", *blk); | |
475 | + q_warn(KERN_ERR "VFS: Can't read quota data block %u\n", *blk); | |
468 | 476 | goto out_buf; |
469 | 477 | } |
470 | 478 | newblk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]); |
... | ... | @@ -488,7 +496,7 @@ |
488 | 496 | } else { |
489 | 497 | ret = write_blk(info, *blk, buf); |
490 | 498 | if (ret < 0) |
491 | - printk(KERN_ERR "VFS: Can't write quota tree " | |
499 | + q_warn(KERN_ERR "VFS: Can't write quota tree " | |
492 | 500 | "block %u.\n", *blk); |
493 | 501 | } |
494 | 502 | } |
... | ... | @@ -521,7 +529,7 @@ |
521 | 529 | return -ENOMEM; |
522 | 530 | ret = read_blk(info, blk, buf); |
523 | 531 | if (ret < 0) { |
524 | - printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk); | |
532 | + q_warn(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk); | |
525 | 533 | goto out_buf; |
526 | 534 | } |
527 | 535 | ddquot = buf + sizeof(struct qt_disk_dqdbheader); |
... | ... | @@ -531,7 +539,7 @@ |
531 | 539 | ddquot += info->dqi_entry_size; |
532 | 540 | } |
533 | 541 | if (i == qtree_dqstr_in_blk(info)) { |
534 | - printk(KERN_ERR "VFS: Quota for id %u referenced " | |
542 | + q_warn(KERN_ERR "VFS: Quota for id %u referenced " | |
535 | 543 | "but not present.\n", dquot->dq_id); |
536 | 544 | ret = -EIO; |
537 | 545 | goto out_buf; |
... | ... | @@ -556,7 +564,7 @@ |
556 | 564 | return -ENOMEM; |
557 | 565 | ret = read_blk(info, blk, buf); |
558 | 566 | if (ret < 0) { |
559 | - printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk); | |
567 | + q_warn(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk); | |
560 | 568 | goto out_buf; |
561 | 569 | } |
562 | 570 | ret = 0; |
... | ... | @@ -599,7 +607,7 @@ |
599 | 607 | offset = find_dqentry(info, dquot); |
600 | 608 | if (offset <= 0) { /* Entry not present? */ |
601 | 609 | if (offset < 0) |
602 | - printk(KERN_ERR "VFS: Can't read quota " | |
610 | + q_warn(KERN_ERR "VFS: Can't read quota " | |
603 | 611 | "structure for id %u.\n", dquot->dq_id); |
604 | 612 | dquot->dq_off = 0; |
605 | 613 | set_bit(DQ_FAKE_B, &dquot->dq_flags); |
... | ... | @@ -617,7 +625,7 @@ |
617 | 625 | if (ret != info->dqi_entry_size) { |
618 | 626 | if (ret >= 0) |
619 | 627 | ret = -EIO; |
620 | - printk(KERN_ERR "VFS: Error while reading quota " | |
628 | + q_warn(KERN_ERR "VFS: Error while reading quota " | |
621 | 629 | "structure for id %u.\n", dquot->dq_id); |
622 | 630 | set_bit(DQ_FAKE_B, &dquot->dq_flags); |
623 | 631 | memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk)); |
fs/quota/quota_tree.h
fs/quota/quota_v2.c
... | ... | @@ -63,7 +63,7 @@ |
63 | 63 | size = sb->s_op->quota_read(sb, type, (char *)dqhead, |
64 | 64 | sizeof(struct v2_disk_dqheader), 0); |
65 | 65 | if (size != sizeof(struct v2_disk_dqheader)) { |
66 | - printk(KERN_WARNING "quota_v2: Failed header read:" | |
66 | + q_warn(KERN_WARNING "quota_v2: Failed header read:" | |
67 | 67 | " expected=%zd got=%zd\n", |
68 | 68 | sizeof(struct v2_disk_dqheader), size); |
69 | 69 | return 0; |
... | ... | @@ -106,7 +106,7 @@ |
106 | 106 | size = sb->s_op->quota_read(sb, type, (char *)&dinfo, |
107 | 107 | sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF); |
108 | 108 | if (size != sizeof(struct v2_disk_dqinfo)) { |
109 | - printk(KERN_WARNING "quota_v2: Can't read info structure on device %s.\n", | |
109 | + q_warn(KERN_WARNING "quota_v2: Can't read info structure on device %s.\n", | |
110 | 110 | sb->s_id); |
111 | 111 | return -1; |
112 | 112 | } |
... | ... | @@ -167,7 +167,7 @@ |
167 | 167 | size = sb->s_op->quota_write(sb, type, (char *)&dinfo, |
168 | 168 | sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF); |
169 | 169 | if (size != sizeof(struct v2_disk_dqinfo)) { |
170 | - printk(KERN_WARNING "Can't write info structure on device %s.\n", | |
170 | + q_warn(KERN_WARNING "Can't write info structure on device %s.\n", | |
171 | 171 | sb->s_id); |
172 | 172 | return -1; |
173 | 173 | } |