aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-01-15 14:51:51 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2016-01-15 14:51:51 -0500
commit1d3671df72e0fe28d7cc686cb432e87c06f4accc (patch)
tree75bf9bdc327bd12d7ed0ca6ee5d1b0254c4753a4
parent875fc4f5ddf35605581f9a5900c14afef48611f2 (diff)
parentbb00c898ad1ce40c4bb422a8207ae562e9aea7ae (diff)
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull UDF fixes and quota cleanups from Jan Kara: "Several UDF fixes and some minor quota cleanups" * 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: udf: Check output buffer length when converting name to CS0 udf: Prevent buffer overrun with multi-byte characters quota: constify qtree_fmt_operations structures udf: avoid uninitialized variable use udf: Fix lost indirect extent block udf: Factor out code for creating indirect extent udf: limit the maximum number of indirect extents in a row udf: limit the maximum number of TD redirections fs: make quota/dquot.c explicitly non-modular fs: make quota/netlink.c explicitly non-modular
-rw-r--r--fs/ocfs2/quota.h2
-rw-r--r--fs/ocfs2/quota_global.c2
-rw-r--r--fs/quota/dquot.c2
-rw-r--r--fs/quota/netlink.c5
-rw-r--r--fs/quota/quota_v2.c4
-rw-r--r--fs/udf/balloc.c98
-rw-r--r--fs/udf/inode.c243
-rw-r--r--fs/udf/super.c14
-rw-r--r--fs/udf/udfdecl.h4
-rw-r--r--fs/udf/unicode.c21
-rw-r--r--include/linux/dqblk_qtree.h2
11 files changed, 196 insertions, 201 deletions
diff --git a/fs/ocfs2/quota.h b/fs/ocfs2/quota.h
index b6d51333ad02..d153e6e31529 100644
--- a/fs/ocfs2/quota.h
+++ b/fs/ocfs2/quota.h
@@ -82,7 +82,7 @@ struct ocfs2_quota_chunk {
82extern struct kmem_cache *ocfs2_dquot_cachep; 82extern struct kmem_cache *ocfs2_dquot_cachep;
83extern struct kmem_cache *ocfs2_qf_chunk_cachep; 83extern struct kmem_cache *ocfs2_qf_chunk_cachep;
84 84
85extern struct qtree_fmt_operations ocfs2_global_ops; 85extern const struct qtree_fmt_operations ocfs2_global_ops;
86 86
87struct ocfs2_quota_recovery *ocfs2_begin_quota_recovery( 87struct ocfs2_quota_recovery *ocfs2_begin_quota_recovery(
88 struct ocfs2_super *osb, int slot_num); 88 struct ocfs2_super *osb, int slot_num);
diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c
index c93d67220887..fde9ef18cff3 100644
--- a/fs/ocfs2/quota_global.c
+++ b/fs/ocfs2/quota_global.c
@@ -123,7 +123,7 @@ static int ocfs2_global_is_id(void *dp, struct dquot *dquot)
123 dquot->dq_id); 123 dquot->dq_id);
124} 124}
125 125
126struct qtree_fmt_operations ocfs2_global_ops = { 126const struct qtree_fmt_operations ocfs2_global_ops = {
127 .mem2disk_dqblk = ocfs2_global_mem2diskdqb, 127 .mem2disk_dqblk = ocfs2_global_mem2diskdqb,
128 .disk2mem_dqblk = ocfs2_global_disk2memdqb, 128 .disk2mem_dqblk = ocfs2_global_disk2memdqb,
129 .is_id = ocfs2_global_is_id, 129 .is_id = ocfs2_global_is_id,
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index ef0d64b2a6d9..fbd70af98820 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -2924,4 +2924,4 @@ static int __init dquot_init(void)
2924 2924
2925 return 0; 2925 return 0;
2926} 2926}
2927module_init(dquot_init); 2927fs_initcall(dquot_init);
diff --git a/fs/quota/netlink.c b/fs/quota/netlink.c
index bb2869f5dfd8..d07a2f91d858 100644
--- a/fs/quota/netlink.c
+++ b/fs/quota/netlink.c
@@ -1,7 +1,5 @@
1
2#include <linux/cred.h> 1#include <linux/cred.h>
3#include <linux/init.h> 2#include <linux/init.h>
4#include <linux/module.h>
5#include <linux/kernel.h> 3#include <linux/kernel.h>
6#include <linux/quotaops.h> 4#include <linux/quotaops.h>
7#include <linux/sched.h> 5#include <linux/sched.h>
@@ -105,5 +103,4 @@ static int __init quota_init(void)
105 "VFS: Failed to create quota netlink interface.\n"); 103 "VFS: Failed to create quota netlink interface.\n");
106 return 0; 104 return 0;
107}; 105};
108 106fs_initcall(quota_init);
109module_init(quota_init);
diff --git a/fs/quota/quota_v2.c b/fs/quota/quota_v2.c
index 2aa012a68e90..ed85d4f35c04 100644
--- a/fs/quota/quota_v2.c
+++ b/fs/quota/quota_v2.c
@@ -30,13 +30,13 @@ static void v2r1_mem2diskdqb(void *dp, struct dquot *dquot);
30static void v2r1_disk2memdqb(struct dquot *dquot, void *dp); 30static void v2r1_disk2memdqb(struct dquot *dquot, void *dp);
31static int v2r1_is_id(void *dp, struct dquot *dquot); 31static int v2r1_is_id(void *dp, struct dquot *dquot);
32 32
33static struct qtree_fmt_operations v2r0_qtree_ops = { 33static const struct qtree_fmt_operations v2r0_qtree_ops = {
34 .mem2disk_dqblk = v2r0_mem2diskdqb, 34 .mem2disk_dqblk = v2r0_mem2diskdqb,
35 .disk2mem_dqblk = v2r0_disk2memdqb, 35 .disk2mem_dqblk = v2r0_disk2memdqb,
36 .is_id = v2r0_is_id, 36 .is_id = v2r0_is_id,
37}; 37};
38 38
39static struct qtree_fmt_operations v2r1_qtree_ops = { 39static const struct qtree_fmt_operations v2r1_qtree_ops = {
40 .mem2disk_dqblk = v2r1_mem2diskdqb, 40 .mem2disk_dqblk = v2r1_mem2diskdqb,
41 .disk2mem_dqblk = v2r1_disk2memdqb, 41 .disk2mem_dqblk = v2r1_disk2memdqb,
42 .is_id = v2r1_is_id, 42 .is_id = v2r1_is_id,
diff --git a/fs/udf/balloc.c b/fs/udf/balloc.c
index 6d6a96b4e73f..e0fd65fe73e8 100644
--- a/fs/udf/balloc.c
+++ b/fs/udf/balloc.c
@@ -447,9 +447,6 @@ static void udf_table_free_blocks(struct super_block *sb,
447 */ 447 */
448 448
449 int adsize; 449 int adsize;
450 struct short_ad *sad = NULL;
451 struct long_ad *lad = NULL;
452 struct allocExtDesc *aed;
453 450
454 eloc.logicalBlockNum = start; 451 eloc.logicalBlockNum = start;
455 elen = EXT_RECORDED_ALLOCATED | 452 elen = EXT_RECORDED_ALLOCATED |
@@ -466,102 +463,17 @@ static void udf_table_free_blocks(struct super_block *sb,
466 } 463 }
467 464
468 if (epos.offset + (2 * adsize) > sb->s_blocksize) { 465 if (epos.offset + (2 * adsize) > sb->s_blocksize) {
469 unsigned char *sptr, *dptr;
470 int loffset;
471
472 brelse(oepos.bh);
473 oepos = epos;
474
475 /* Steal a block from the extent being free'd */ 466 /* Steal a block from the extent being free'd */
476 epos.block.logicalBlockNum = eloc.logicalBlockNum; 467 udf_setup_indirect_aext(table, eloc.logicalBlockNum,
468 &epos);
469
477 eloc.logicalBlockNum++; 470 eloc.logicalBlockNum++;
478 elen -= sb->s_blocksize; 471 elen -= sb->s_blocksize;
479
480 epos.bh = udf_tread(sb,
481 udf_get_lb_pblock(sb, &epos.block, 0));
482 if (!epos.bh) {
483 brelse(oepos.bh);
484 goto error_return;
485 }
486 aed = (struct allocExtDesc *)(epos.bh->b_data);
487 aed->previousAllocExtLocation =
488 cpu_to_le32(oepos.block.logicalBlockNum);
489 if (epos.offset + adsize > sb->s_blocksize) {
490 loffset = epos.offset;
491 aed->lengthAllocDescs = cpu_to_le32(adsize);
492 sptr = iinfo->i_ext.i_data + epos.offset
493 - adsize;
494 dptr = epos.bh->b_data +
495 sizeof(struct allocExtDesc);
496 memcpy(dptr, sptr, adsize);
497 epos.offset = sizeof(struct allocExtDesc) +
498 adsize;
499 } else {
500 loffset = epos.offset + adsize;
501 aed->lengthAllocDescs = cpu_to_le32(0);
502 if (oepos.bh) {
503 sptr = oepos.bh->b_data + epos.offset;
504 aed = (struct allocExtDesc *)
505 oepos.bh->b_data;
506 le32_add_cpu(&aed->lengthAllocDescs,
507 adsize);
508 } else {
509 sptr = iinfo->i_ext.i_data +
510 epos.offset;
511 iinfo->i_lenAlloc += adsize;
512 mark_inode_dirty(table);
513 }
514 epos.offset = sizeof(struct allocExtDesc);
515 }
516 if (sbi->s_udfrev >= 0x0200)
517 udf_new_tag(epos.bh->b_data, TAG_IDENT_AED,
518 3, 1, epos.block.logicalBlockNum,
519 sizeof(struct tag));
520 else
521 udf_new_tag(epos.bh->b_data, TAG_IDENT_AED,
522 2, 1, epos.block.logicalBlockNum,
523 sizeof(struct tag));
524
525 switch (iinfo->i_alloc_type) {
526 case ICBTAG_FLAG_AD_SHORT:
527 sad = (struct short_ad *)sptr;
528 sad->extLength = cpu_to_le32(
529 EXT_NEXT_EXTENT_ALLOCDECS |
530 sb->s_blocksize);
531 sad->extPosition =
532 cpu_to_le32(epos.block.logicalBlockNum);
533 break;
534 case ICBTAG_FLAG_AD_LONG:
535 lad = (struct long_ad *)sptr;
536 lad->extLength = cpu_to_le32(
537 EXT_NEXT_EXTENT_ALLOCDECS |
538 sb->s_blocksize);
539 lad->extLocation =
540 cpu_to_lelb(epos.block);
541 break;
542 }
543 if (oepos.bh) {
544 udf_update_tag(oepos.bh->b_data, loffset);
545 mark_buffer_dirty(oepos.bh);
546 } else {
547 mark_inode_dirty(table);
548 }
549 } 472 }
550 473
551 /* It's possible that stealing the block emptied the extent */ 474 /* It's possible that stealing the block emptied the extent */
552 if (elen) { 475 if (elen)
553 udf_write_aext(table, &epos, &eloc, elen, 1); 476 __udf_add_aext(table, &epos, &eloc, elen, 1);
554
555 if (!epos.bh) {
556 iinfo->i_lenAlloc += adsize;
557 mark_inode_dirty(table);
558 } else {
559 aed = (struct allocExtDesc *)epos.bh->b_data;
560 le32_add_cpu(&aed->lengthAllocDescs, adsize);
561 udf_update_tag(epos.bh->b_data, epos.offset);
562 mark_buffer_dirty(epos.bh);
563 }
564 }
565 } 477 }
566 478
567 brelse(epos.bh); 479 brelse(epos.bh);
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 055746350d16..87dc16d15572 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -539,9 +539,18 @@ static int udf_do_extend_file(struct inode *inode,
539 udf_add_aext(inode, last_pos, &last_ext->extLocation, 539 udf_add_aext(inode, last_pos, &last_ext->extLocation,
540 last_ext->extLength, 1); 540 last_ext->extLength, 1);
541 count++; 541 count++;
542 } else 542 } else {
543 struct kernel_lb_addr tmploc;
544 uint32_t tmplen;
545
543 udf_write_aext(inode, last_pos, &last_ext->extLocation, 546 udf_write_aext(inode, last_pos, &last_ext->extLocation,
544 last_ext->extLength, 1); 547 last_ext->extLength, 1);
548 /*
549 * We've rewritten the last extent but there may be empty
550 * indirect extent after it - enter it.
551 */
552 udf_next_aext(inode, last_pos, &tmploc, &tmplen, 0);
553 }
545 554
546 /* Managed to do everything necessary? */ 555 /* Managed to do everything necessary? */
547 if (!blocks) 556 if (!blocks)
@@ -1867,22 +1876,90 @@ struct inode *__udf_iget(struct super_block *sb, struct kernel_lb_addr *ino,
1867 return inode; 1876 return inode;
1868} 1877}
1869 1878
1870int udf_add_aext(struct inode *inode, struct extent_position *epos, 1879int udf_setup_indirect_aext(struct inode *inode, int block,
1871 struct kernel_lb_addr *eloc, uint32_t elen, int inc) 1880 struct extent_position *epos)
1872{ 1881{
1873 int adsize; 1882 struct super_block *sb = inode->i_sb;
1874 struct short_ad *sad = NULL; 1883 struct buffer_head *bh;
1875 struct long_ad *lad = NULL;
1876 struct allocExtDesc *aed; 1884 struct allocExtDesc *aed;
1877 uint8_t *ptr; 1885 struct extent_position nepos;
1878 struct udf_inode_info *iinfo = UDF_I(inode); 1886 struct kernel_lb_addr neloc;
1887 int ver, adsize;
1879 1888
1880 if (!epos->bh) 1889 if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
1881 ptr = iinfo->i_ext.i_data + epos->offset - 1890 adsize = sizeof(struct short_ad);
1882 udf_file_entry_alloc_offset(inode) + 1891 else if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_LONG)
1883 iinfo->i_lenEAttr; 1892 adsize = sizeof(struct long_ad);
1884 else 1893 else
1885 ptr = epos->bh->b_data + epos->offset; 1894 return -EIO;
1895
1896 neloc.logicalBlockNum = block;
1897 neloc.partitionReferenceNum = epos->block.partitionReferenceNum;
1898
1899 bh = udf_tgetblk(sb, udf_get_lb_pblock(sb, &neloc, 0));
1900 if (!bh)
1901 return -EIO;
1902 lock_buffer(bh);
1903 memset(bh->b_data, 0x00, sb->s_blocksize);
1904 set_buffer_uptodate(bh);
1905 unlock_buffer(bh);
1906 mark_buffer_dirty_inode(bh, inode);
1907
1908 aed = (struct allocExtDesc *)(bh->b_data);
1909 if (!UDF_QUERY_FLAG(sb, UDF_FLAG_STRICT)) {
1910 aed->previousAllocExtLocation =
1911 cpu_to_le32(epos->block.logicalBlockNum);
1912 }
1913 aed->lengthAllocDescs = cpu_to_le32(0);
1914 if (UDF_SB(sb)->s_udfrev >= 0x0200)
1915 ver = 3;
1916 else
1917 ver = 2;
1918 udf_new_tag(bh->b_data, TAG_IDENT_AED, ver, 1, block,
1919 sizeof(struct tag));
1920
1921 nepos.block = neloc;
1922 nepos.offset = sizeof(struct allocExtDesc);
1923 nepos.bh = bh;
1924
1925 /*
1926 * Do we have to copy current last extent to make space for indirect
1927 * one?
1928 */
1929 if (epos->offset + adsize > sb->s_blocksize) {
1930 struct kernel_lb_addr cp_loc;
1931 uint32_t cp_len;
1932 int cp_type;
1933
1934 epos->offset -= adsize;
1935 cp_type = udf_current_aext(inode, epos, &cp_loc, &cp_len, 0);
1936 cp_len |= ((uint32_t)cp_type) << 30;
1937
1938 __udf_add_aext(inode, &nepos, &cp_loc, cp_len, 1);
1939 udf_write_aext(inode, epos, &nepos.block,
1940 sb->s_blocksize | EXT_NEXT_EXTENT_ALLOCDECS, 0);
1941 } else {
1942 __udf_add_aext(inode, epos, &nepos.block,
1943 sb->s_blocksize | EXT_NEXT_EXTENT_ALLOCDECS, 0);
1944 }
1945
1946 brelse(epos->bh);
1947 *epos = nepos;
1948
1949 return 0;
1950}
1951
1952/*
1953 * Append extent at the given position - should be the first free one in inode
1954 * / indirect extent. This function assumes there is enough space in the inode
1955 * or indirect extent. Use udf_add_aext() if you didn't check for this before.
1956 */
1957int __udf_add_aext(struct inode *inode, struct extent_position *epos,
1958 struct kernel_lb_addr *eloc, uint32_t elen, int inc)
1959{
1960 struct udf_inode_info *iinfo = UDF_I(inode);
1961 struct allocExtDesc *aed;
1962 int adsize;
1886 1963
1887 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT) 1964 if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
1888 adsize = sizeof(struct short_ad); 1965 adsize = sizeof(struct short_ad);
@@ -1891,88 +1968,14 @@ int udf_add_aext(struct inode *inode, struct extent_position *epos,
1891 else 1968 else
1892 return -EIO; 1969 return -EIO;
1893 1970
1894 if (epos->offset + (2 * adsize) > inode->i_sb->s_blocksize) { 1971 if (!epos->bh) {
1895 unsigned char *sptr, *dptr; 1972 WARN_ON(iinfo->i_lenAlloc !=
1896 struct buffer_head *nbh; 1973 epos->offset - udf_file_entry_alloc_offset(inode));
1897 int err, loffset; 1974 } else {
1898 struct kernel_lb_addr obloc = epos->block; 1975 aed = (struct allocExtDesc *)epos->bh->b_data;
1899 1976 WARN_ON(le32_to_cpu(aed->lengthAllocDescs) !=
1900 epos->block.logicalBlockNum = udf_new_block(inode->i_sb, NULL, 1977 epos->offset - sizeof(struct allocExtDesc));
1901 obloc.partitionReferenceNum, 1978 WARN_ON(epos->offset + adsize > inode->i_sb->s_blocksize);
1902 obloc.logicalBlockNum, &err);
1903 if (!epos->block.logicalBlockNum)
1904 return -ENOSPC;
1905 nbh = udf_tgetblk(inode->i_sb, udf_get_lb_pblock(inode->i_sb,
1906 &epos->block,
1907 0));
1908 if (!nbh)
1909 return -EIO;
1910 lock_buffer(nbh);
1911 memset(nbh->b_data, 0x00, inode->i_sb->s_blocksize);
1912 set_buffer_uptodate(nbh);
1913 unlock_buffer(nbh);
1914 mark_buffer_dirty_inode(nbh, inode);
1915
1916 aed = (struct allocExtDesc *)(nbh->b_data);
1917 if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT))
1918 aed->previousAllocExtLocation =
1919 cpu_to_le32(obloc.logicalBlockNum);
1920 if (epos->offset + adsize > inode->i_sb->s_blocksize) {
1921 loffset = epos->offset;
1922 aed->lengthAllocDescs = cpu_to_le32(adsize);
1923 sptr = ptr - adsize;
1924 dptr = nbh->b_data + sizeof(struct allocExtDesc);
1925 memcpy(dptr, sptr, adsize);
1926 epos->offset = sizeof(struct allocExtDesc) + adsize;
1927 } else {
1928 loffset = epos->offset + adsize;
1929 aed->lengthAllocDescs = cpu_to_le32(0);
1930 sptr = ptr;
1931 epos->offset = sizeof(struct allocExtDesc);
1932
1933 if (epos->bh) {
1934 aed = (struct allocExtDesc *)epos->bh->b_data;
1935 le32_add_cpu(&aed->lengthAllocDescs, adsize);
1936 } else {
1937 iinfo->i_lenAlloc += adsize;
1938 mark_inode_dirty(inode);
1939 }
1940 }
1941 if (UDF_SB(inode->i_sb)->s_udfrev >= 0x0200)
1942 udf_new_tag(nbh->b_data, TAG_IDENT_AED, 3, 1,
1943 epos->block.logicalBlockNum, sizeof(struct tag));
1944 else
1945 udf_new_tag(nbh->b_data, TAG_IDENT_AED, 2, 1,
1946 epos->block.logicalBlockNum, sizeof(struct tag));
1947 switch (iinfo->i_alloc_type) {
1948 case ICBTAG_FLAG_AD_SHORT:
1949 sad = (struct short_ad *)sptr;
1950 sad->extLength = cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS |
1951 inode->i_sb->s_blocksize);
1952 sad->extPosition =
1953 cpu_to_le32(epos->block.logicalBlockNum);
1954 break;
1955 case ICBTAG_FLAG_AD_LONG:
1956 lad = (struct long_ad *)sptr;
1957 lad->extLength = cpu_to_le32(EXT_NEXT_EXTENT_ALLOCDECS |
1958 inode->i_sb->s_blocksize);
1959 lad->extLocation = cpu_to_lelb(epos->block);
1960 memset(lad->impUse, 0x00, sizeof(lad->impUse));
1961 break;
1962 }
1963 if (epos->bh) {
1964 if (!UDF_QUERY_FLAG(inode->i_sb, UDF_FLAG_STRICT) ||
1965 UDF_SB(inode->i_sb)->s_udfrev >= 0x0201)
1966 udf_update_tag(epos->bh->b_data, loffset);
1967 else
1968 udf_update_tag(epos->bh->b_data,
1969 sizeof(struct allocExtDesc));
1970 mark_buffer_dirty_inode(epos->bh, inode);
1971 brelse(epos->bh);
1972 } else {
1973 mark_inode_dirty(inode);
1974 }
1975 epos->bh = nbh;
1976 } 1979 }
1977 1980
1978 udf_write_aext(inode, epos, eloc, elen, inc); 1981 udf_write_aext(inode, epos, eloc, elen, inc);
@@ -1996,6 +1999,41 @@ int udf_add_aext(struct inode *inode, struct extent_position *epos,
1996 return 0; 1999 return 0;
1997} 2000}
1998 2001
2002/*
2003 * Append extent at given position - should be the first free one in inode
2004 * / indirect extent. Takes care of allocating and linking indirect blocks.
2005 */
2006int udf_add_aext(struct inode *inode, struct extent_position *epos,
2007 struct kernel_lb_addr *eloc, uint32_t elen, int inc)
2008{
2009 int adsize;
2010 struct super_block *sb = inode->i_sb;
2011
2012 if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_SHORT)
2013 adsize = sizeof(struct short_ad);
2014 else if (UDF_I(inode)->i_alloc_type == ICBTAG_FLAG_AD_LONG)
2015 adsize = sizeof(struct long_ad);
2016 else
2017 return -EIO;
2018
2019 if (epos->offset + (2 * adsize) > sb->s_blocksize) {
2020 int err;
2021 int new_block;
2022
2023 new_block = udf_new_block(sb, NULL,
2024 epos->block.partitionReferenceNum,
2025 epos->block.logicalBlockNum, &err);
2026 if (!new_block)
2027 return -ENOSPC;
2028
2029 err = udf_setup_indirect_aext(inode, new_block, epos);
2030 if (err)
2031 return err;
2032 }
2033
2034 return __udf_add_aext(inode, epos, eloc, elen, inc);
2035}
2036
1999void udf_write_aext(struct inode *inode, struct extent_position *epos, 2037void udf_write_aext(struct inode *inode, struct extent_position *epos,
2000 struct kernel_lb_addr *eloc, uint32_t elen, int inc) 2038 struct kernel_lb_addr *eloc, uint32_t elen, int inc)
2001{ 2039{
@@ -2048,14 +2086,29 @@ void udf_write_aext(struct inode *inode, struct extent_position *epos,
2048 epos->offset += adsize; 2086 epos->offset += adsize;
2049} 2087}
2050 2088
2089/*
2090 * Only 1 indirect extent in a row really makes sense but allow upto 16 in case
2091 * someone does some weird stuff.
2092 */
2093#define UDF_MAX_INDIR_EXTS 16
2094
2051int8_t udf_next_aext(struct inode *inode, struct extent_position *epos, 2095int8_t udf_next_aext(struct inode *inode, struct extent_position *epos,
2052 struct kernel_lb_addr *eloc, uint32_t *elen, int inc) 2096 struct kernel_lb_addr *eloc, uint32_t *elen, int inc)
2053{ 2097{
2054 int8_t etype; 2098 int8_t etype;
2099 unsigned int indirections = 0;
2055 2100
2056 while ((etype = udf_current_aext(inode, epos, eloc, elen, inc)) == 2101 while ((etype = udf_current_aext(inode, epos, eloc, elen, inc)) ==
2057 (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) { 2102 (EXT_NEXT_EXTENT_ALLOCDECS >> 30)) {
2058 int block; 2103 int block;
2104
2105 if (++indirections > UDF_MAX_INDIR_EXTS) {
2106 udf_err(inode->i_sb,
2107 "too many indirect extents in inode %lu\n",
2108 inode->i_ino);
2109 return -1;
2110 }
2111
2059 epos->block = *eloc; 2112 epos->block = *eloc;
2060 epos->offset = sizeof(struct allocExtDesc); 2113 epos->offset = sizeof(struct allocExtDesc);
2061 brelse(epos->bh); 2114 brelse(epos->bh);
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 9c64a3ca9837..0fbb4c7c72e8 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -1587,6 +1587,13 @@ static void udf_load_logicalvolint(struct super_block *sb, struct kernel_extent_
1587} 1587}
1588 1588
1589/* 1589/*
1590 * Maximum number of Terminating Descriptor redirections. The chosen number is
1591 * arbitrary - just that we hopefully don't limit any real use of rewritten
1592 * inode on write-once media but avoid looping for too long on corrupted media.
1593 */
1594#define UDF_MAX_TD_NESTING 64
1595
1596/*
1590 * Process a main/reserve volume descriptor sequence. 1597 * Process a main/reserve volume descriptor sequence.
1591 * @block First block of first extent of the sequence. 1598 * @block First block of first extent of the sequence.
1592 * @lastblock Lastblock of first extent of the sequence. 1599 * @lastblock Lastblock of first extent of the sequence.
@@ -1610,6 +1617,7 @@ static noinline int udf_process_sequence(
1610 uint16_t ident; 1617 uint16_t ident;
1611 long next_s = 0, next_e = 0; 1618 long next_s = 0, next_e = 0;
1612 int ret; 1619 int ret;
1620 unsigned int indirections = 0;
1613 1621
1614 memset(vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH); 1622 memset(vds, 0, sizeof(struct udf_vds_record) * VDS_POS_LENGTH);
1615 1623
@@ -1680,6 +1688,12 @@ static noinline int udf_process_sequence(
1680 } 1688 }
1681 break; 1689 break;
1682 case TAG_IDENT_TD: /* ISO 13346 3/10.9 */ 1690 case TAG_IDENT_TD: /* ISO 13346 3/10.9 */
1691 if (++indirections > UDF_MAX_TD_NESTING) {
1692 udf_err(sb, "too many TDs (max %u supported)\n", UDF_MAX_TD_NESTING);
1693 brelse(bh);
1694 return -EIO;
1695 }
1696
1683 vds[VDS_POS_TERMINATING_DESC].block = block; 1697 vds[VDS_POS_TERMINATING_DESC].block = block;
1684 if (next_e) { 1698 if (next_e) {
1685 block = next_s; 1699 block = next_s;
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index ce169b49429d..fa0044b6b81d 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -158,6 +158,10 @@ extern int udf_write_inode(struct inode *, struct writeback_control *wbc);
158extern long udf_block_map(struct inode *, sector_t); 158extern long udf_block_map(struct inode *, sector_t);
159extern int8_t inode_bmap(struct inode *, sector_t, struct extent_position *, 159extern int8_t inode_bmap(struct inode *, sector_t, struct extent_position *,
160 struct kernel_lb_addr *, uint32_t *, sector_t *); 160 struct kernel_lb_addr *, uint32_t *, sector_t *);
161extern int udf_setup_indirect_aext(struct inode *inode, int block,
162 struct extent_position *epos);
163extern int __udf_add_aext(struct inode *inode, struct extent_position *epos,
164 struct kernel_lb_addr *eloc, uint32_t elen, int inc);
161extern int udf_add_aext(struct inode *, struct extent_position *, 165extern int udf_add_aext(struct inode *, struct extent_position *,
162 struct kernel_lb_addr *, uint32_t, int); 166 struct kernel_lb_addr *, uint32_t, int);
163extern void udf_write_aext(struct inode *, struct extent_position *, 167extern void udf_write_aext(struct inode *, struct extent_position *,
diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c
index ab478e62baae..e788a05aab83 100644
--- a/fs/udf/unicode.c
+++ b/fs/udf/unicode.c
@@ -128,11 +128,15 @@ int udf_CS0toUTF8(struct ustr *utf_o, const struct ustr *ocu_i)
128 if (c < 0x80U) 128 if (c < 0x80U)
129 utf_o->u_name[utf_o->u_len++] = (uint8_t)c; 129 utf_o->u_name[utf_o->u_len++] = (uint8_t)c;
130 else if (c < 0x800U) { 130 else if (c < 0x800U) {
131 if (utf_o->u_len > (UDF_NAME_LEN - 4))
132 break;
131 utf_o->u_name[utf_o->u_len++] = 133 utf_o->u_name[utf_o->u_len++] =
132 (uint8_t)(0xc0 | (c >> 6)); 134 (uint8_t)(0xc0 | (c >> 6));
133 utf_o->u_name[utf_o->u_len++] = 135 utf_o->u_name[utf_o->u_len++] =
134 (uint8_t)(0x80 | (c & 0x3f)); 136 (uint8_t)(0x80 | (c & 0x3f));
135 } else { 137 } else {
138 if (utf_o->u_len > (UDF_NAME_LEN - 5))
139 break;
136 utf_o->u_name[utf_o->u_len++] = 140 utf_o->u_name[utf_o->u_len++] =
137 (uint8_t)(0xe0 | (c >> 12)); 141 (uint8_t)(0xe0 | (c >> 12));
138 utf_o->u_name[utf_o->u_len++] = 142 utf_o->u_name[utf_o->u_len++] =
@@ -173,17 +177,22 @@ int udf_CS0toUTF8(struct ustr *utf_o, const struct ustr *ocu_i)
173static int udf_UTF8toCS0(dstring *ocu, struct ustr *utf, int length) 177static int udf_UTF8toCS0(dstring *ocu, struct ustr *utf, int length)
174{ 178{
175 unsigned c, i, max_val, utf_char; 179 unsigned c, i, max_val, utf_char;
176 int utf_cnt, u_len; 180 int utf_cnt, u_len, u_ch;
177 181
178 memset(ocu, 0, sizeof(dstring) * length); 182 memset(ocu, 0, sizeof(dstring) * length);
179 ocu[0] = 8; 183 ocu[0] = 8;
180 max_val = 0xffU; 184 max_val = 0xffU;
185 u_ch = 1;
181 186
182try_again: 187try_again:
183 u_len = 0U; 188 u_len = 0U;
184 utf_char = 0U; 189 utf_char = 0U;
185 utf_cnt = 0U; 190 utf_cnt = 0U;
186 for (i = 0U; i < utf->u_len; i++) { 191 for (i = 0U; i < utf->u_len; i++) {
192 /* Name didn't fit? */
193 if (u_len + 1 + u_ch >= length)
194 return 0;
195
187 c = (uint8_t)utf->u_name[i]; 196 c = (uint8_t)utf->u_name[i];
188 197
189 /* Complete a multi-byte UTF-8 character */ 198 /* Complete a multi-byte UTF-8 character */
@@ -225,6 +234,7 @@ try_again:
225 if (max_val == 0xffU) { 234 if (max_val == 0xffU) {
226 max_val = 0xffffU; 235 max_val = 0xffffU;
227 ocu[0] = (uint8_t)0x10U; 236 ocu[0] = (uint8_t)0x10U;
237 u_ch = 2;
228 goto try_again; 238 goto try_again;
229 } 239 }
230 goto error_out; 240 goto error_out;
@@ -277,7 +287,7 @@ static int udf_CS0toNLS(struct nls_table *nls, struct ustr *utf_o,
277 c = (c << 8) | ocu[i++]; 287 c = (c << 8) | ocu[i++];
278 288
279 len = nls->uni2char(c, &utf_o->u_name[utf_o->u_len], 289 len = nls->uni2char(c, &utf_o->u_name[utf_o->u_len],
280 UDF_NAME_LEN - utf_o->u_len); 290 UDF_NAME_LEN - 2 - utf_o->u_len);
281 /* Valid character? */ 291 /* Valid character? */
282 if (len >= 0) 292 if (len >= 0)
283 utf_o->u_len += len; 293 utf_o->u_len += len;
@@ -295,15 +305,19 @@ static int udf_NLStoCS0(struct nls_table *nls, dstring *ocu, struct ustr *uni,
295 int len; 305 int len;
296 unsigned i, max_val; 306 unsigned i, max_val;
297 uint16_t uni_char; 307 uint16_t uni_char;
298 int u_len; 308 int u_len, u_ch;
299 309
300 memset(ocu, 0, sizeof(dstring) * length); 310 memset(ocu, 0, sizeof(dstring) * length);
301 ocu[0] = 8; 311 ocu[0] = 8;
302 max_val = 0xffU; 312 max_val = 0xffU;
313 u_ch = 1;
303 314
304try_again: 315try_again:
305 u_len = 0U; 316 u_len = 0U;
306 for (i = 0U; i < uni->u_len; i++) { 317 for (i = 0U; i < uni->u_len; i++) {
318 /* Name didn't fit? */
319 if (u_len + 1 + u_ch >= length)
320 return 0;
307 len = nls->char2uni(&uni->u_name[i], uni->u_len - i, &uni_char); 321 len = nls->char2uni(&uni->u_name[i], uni->u_len - i, &uni_char);
308 if (!len) 322 if (!len)
309 continue; 323 continue;
@@ -316,6 +330,7 @@ try_again:
316 if (uni_char > max_val) { 330 if (uni_char > max_val) {
317 max_val = 0xffffU; 331 max_val = 0xffffU;
318 ocu[0] = (uint8_t)0x10U; 332 ocu[0] = (uint8_t)0x10U;
333 u_ch = 2;
319 goto try_again; 334 goto try_again;
320 } 335 }
321 336
diff --git a/include/linux/dqblk_qtree.h b/include/linux/dqblk_qtree.h
index 82a16527b367..ff8b55359648 100644
--- a/include/linux/dqblk_qtree.h
+++ b/include/linux/dqblk_qtree.h
@@ -34,7 +34,7 @@ struct qtree_mem_dqinfo {
34 unsigned int dqi_entry_size; /* Size of quota entry in quota file */ 34 unsigned int dqi_entry_size; /* Size of quota entry in quota file */
35 unsigned int dqi_usable_bs; /* Space usable in block for quota data */ 35 unsigned int dqi_usable_bs; /* Space usable in block for quota data */
36 unsigned int dqi_qtree_depth; /* Precomputed depth of quota tree */ 36 unsigned int dqi_qtree_depth; /* Precomputed depth of quota tree */
37 struct qtree_fmt_operations *dqi_ops; /* Operations for entry manipulation */ 37 const struct qtree_fmt_operations *dqi_ops; /* Operations for entry manipulation */
38}; 38};
39 39
40int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot); 40int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot);