diff options
Diffstat (limited to 'fs/udf/super.c')
-rw-r--r-- | fs/udf/super.c | 51 |
1 files changed, 33 insertions, 18 deletions
diff --git a/fs/udf/super.c b/fs/udf/super.c index e3d684ea3203..ffd8038ff728 100644 --- a/fs/udf/super.c +++ b/fs/udf/super.c | |||
@@ -1474,6 +1474,17 @@ static int udf_load_logicalvol(struct super_block *sb, sector_t block, | |||
1474 | if (lvd->integritySeqExt.extLength) | 1474 | if (lvd->integritySeqExt.extLength) |
1475 | udf_load_logicalvolint(sb, leea_to_cpu(lvd->integritySeqExt)); | 1475 | udf_load_logicalvolint(sb, leea_to_cpu(lvd->integritySeqExt)); |
1476 | ret = 0; | 1476 | ret = 0; |
1477 | |||
1478 | if (!sbi->s_lvid_bh) { | ||
1479 | /* We can't generate unique IDs without a valid LVID */ | ||
1480 | if (sb_rdonly(sb)) { | ||
1481 | UDF_SET_FLAG(sb, UDF_FLAG_RW_INCOMPAT); | ||
1482 | } else { | ||
1483 | udf_warn(sb, "Damaged or missing LVID, forcing " | ||
1484 | "readonly mount\n"); | ||
1485 | ret = -EACCES; | ||
1486 | } | ||
1487 | } | ||
1477 | out_bh: | 1488 | out_bh: |
1478 | brelse(bh); | 1489 | brelse(bh); |
1479 | return ret; | 1490 | return ret; |
@@ -1943,13 +1954,24 @@ static int udf_load_vrs(struct super_block *sb, struct udf_options *uopt, | |||
1943 | return 0; | 1954 | return 0; |
1944 | } | 1955 | } |
1945 | 1956 | ||
1957 | static void udf_finalize_lvid(struct logicalVolIntegrityDesc *lvid) | ||
1958 | { | ||
1959 | struct timespec64 ts; | ||
1960 | |||
1961 | ktime_get_real_ts64(&ts); | ||
1962 | udf_time_to_disk_stamp(&lvid->recordingDateAndTime, ts); | ||
1963 | lvid->descTag.descCRC = cpu_to_le16( | ||
1964 | crc_itu_t(0, (char *)lvid + sizeof(struct tag), | ||
1965 | le16_to_cpu(lvid->descTag.descCRCLength))); | ||
1966 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); | ||
1967 | } | ||
1968 | |||
1946 | static void udf_open_lvid(struct super_block *sb) | 1969 | static void udf_open_lvid(struct super_block *sb) |
1947 | { | 1970 | { |
1948 | struct udf_sb_info *sbi = UDF_SB(sb); | 1971 | struct udf_sb_info *sbi = UDF_SB(sb); |
1949 | struct buffer_head *bh = sbi->s_lvid_bh; | 1972 | struct buffer_head *bh = sbi->s_lvid_bh; |
1950 | struct logicalVolIntegrityDesc *lvid; | 1973 | struct logicalVolIntegrityDesc *lvid; |
1951 | struct logicalVolIntegrityDescImpUse *lvidiu; | 1974 | struct logicalVolIntegrityDescImpUse *lvidiu; |
1952 | struct timespec64 ts; | ||
1953 | 1975 | ||
1954 | if (!bh) | 1976 | if (!bh) |
1955 | return; | 1977 | return; |
@@ -1961,18 +1983,12 @@ static void udf_open_lvid(struct super_block *sb) | |||
1961 | mutex_lock(&sbi->s_alloc_mutex); | 1983 | mutex_lock(&sbi->s_alloc_mutex); |
1962 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; | 1984 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; |
1963 | lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; | 1985 | lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; |
1964 | ktime_get_real_ts64(&ts); | ||
1965 | udf_time_to_disk_stamp(&lvid->recordingDateAndTime, ts); | ||
1966 | if (le32_to_cpu(lvid->integrityType) == LVID_INTEGRITY_TYPE_CLOSE) | 1986 | if (le32_to_cpu(lvid->integrityType) == LVID_INTEGRITY_TYPE_CLOSE) |
1967 | lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN); | 1987 | lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN); |
1968 | else | 1988 | else |
1969 | UDF_SET_FLAG(sb, UDF_FLAG_INCONSISTENT); | 1989 | UDF_SET_FLAG(sb, UDF_FLAG_INCONSISTENT); |
1970 | 1990 | ||
1971 | lvid->descTag.descCRC = cpu_to_le16( | 1991 | udf_finalize_lvid(lvid); |
1972 | crc_itu_t(0, (char *)lvid + sizeof(struct tag), | ||
1973 | le16_to_cpu(lvid->descTag.descCRCLength))); | ||
1974 | |||
1975 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); | ||
1976 | mark_buffer_dirty(bh); | 1992 | mark_buffer_dirty(bh); |
1977 | sbi->s_lvid_dirty = 0; | 1993 | sbi->s_lvid_dirty = 0; |
1978 | mutex_unlock(&sbi->s_alloc_mutex); | 1994 | mutex_unlock(&sbi->s_alloc_mutex); |
@@ -1986,7 +2002,6 @@ static void udf_close_lvid(struct super_block *sb) | |||
1986 | struct buffer_head *bh = sbi->s_lvid_bh; | 2002 | struct buffer_head *bh = sbi->s_lvid_bh; |
1987 | struct logicalVolIntegrityDesc *lvid; | 2003 | struct logicalVolIntegrityDesc *lvid; |
1988 | struct logicalVolIntegrityDescImpUse *lvidiu; | 2004 | struct logicalVolIntegrityDescImpUse *lvidiu; |
1989 | struct timespec64 ts; | ||
1990 | 2005 | ||
1991 | if (!bh) | 2006 | if (!bh) |
1992 | return; | 2007 | return; |
@@ -1998,8 +2013,6 @@ static void udf_close_lvid(struct super_block *sb) | |||
1998 | mutex_lock(&sbi->s_alloc_mutex); | 2013 | mutex_lock(&sbi->s_alloc_mutex); |
1999 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; | 2014 | lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX; |
2000 | lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; | 2015 | lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX; |
2001 | ktime_get_real_ts64(&ts); | ||
2002 | udf_time_to_disk_stamp(&lvid->recordingDateAndTime, ts); | ||
2003 | if (UDF_MAX_WRITE_VERSION > le16_to_cpu(lvidiu->maxUDFWriteRev)) | 2016 | if (UDF_MAX_WRITE_VERSION > le16_to_cpu(lvidiu->maxUDFWriteRev)) |
2004 | lvidiu->maxUDFWriteRev = cpu_to_le16(UDF_MAX_WRITE_VERSION); | 2017 | lvidiu->maxUDFWriteRev = cpu_to_le16(UDF_MAX_WRITE_VERSION); |
2005 | if (sbi->s_udfrev > le16_to_cpu(lvidiu->minUDFReadRev)) | 2018 | if (sbi->s_udfrev > le16_to_cpu(lvidiu->minUDFReadRev)) |
@@ -2009,17 +2022,13 @@ static void udf_close_lvid(struct super_block *sb) | |||
2009 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_INCONSISTENT)) | 2022 | if (!UDF_QUERY_FLAG(sb, UDF_FLAG_INCONSISTENT)) |
2010 | lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE); | 2023 | lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_CLOSE); |
2011 | 2024 | ||
2012 | lvid->descTag.descCRC = cpu_to_le16( | ||
2013 | crc_itu_t(0, (char *)lvid + sizeof(struct tag), | ||
2014 | le16_to_cpu(lvid->descTag.descCRCLength))); | ||
2015 | |||
2016 | lvid->descTag.tagChecksum = udf_tag_checksum(&lvid->descTag); | ||
2017 | /* | 2025 | /* |
2018 | * We set buffer uptodate unconditionally here to avoid spurious | 2026 | * We set buffer uptodate unconditionally here to avoid spurious |
2019 | * warnings from mark_buffer_dirty() when previous EIO has marked | 2027 | * warnings from mark_buffer_dirty() when previous EIO has marked |
2020 | * the buffer as !uptodate | 2028 | * the buffer as !uptodate |
2021 | */ | 2029 | */ |
2022 | set_buffer_uptodate(bh); | 2030 | set_buffer_uptodate(bh); |
2031 | udf_finalize_lvid(lvid); | ||
2023 | mark_buffer_dirty(bh); | 2032 | mark_buffer_dirty(bh); |
2024 | sbi->s_lvid_dirty = 0; | 2033 | sbi->s_lvid_dirty = 0; |
2025 | mutex_unlock(&sbi->s_alloc_mutex); | 2034 | mutex_unlock(&sbi->s_alloc_mutex); |
@@ -2048,8 +2057,8 @@ u64 lvid_get_unique_id(struct super_block *sb) | |||
2048 | if (!(++uniqueID & 0xFFFFFFFF)) | 2057 | if (!(++uniqueID & 0xFFFFFFFF)) |
2049 | uniqueID += 16; | 2058 | uniqueID += 16; |
2050 | lvhd->uniqueID = cpu_to_le64(uniqueID); | 2059 | lvhd->uniqueID = cpu_to_le64(uniqueID); |
2060 | udf_updated_lvid(sb); | ||
2051 | mutex_unlock(&sbi->s_alloc_mutex); | 2061 | mutex_unlock(&sbi->s_alloc_mutex); |
2052 | mark_buffer_dirty(bh); | ||
2053 | 2062 | ||
2054 | return ret; | 2063 | return ret; |
2055 | } | 2064 | } |
@@ -2320,11 +2329,17 @@ static int udf_sync_fs(struct super_block *sb, int wait) | |||
2320 | 2329 | ||
2321 | mutex_lock(&sbi->s_alloc_mutex); | 2330 | mutex_lock(&sbi->s_alloc_mutex); |
2322 | if (sbi->s_lvid_dirty) { | 2331 | if (sbi->s_lvid_dirty) { |
2332 | struct buffer_head *bh = sbi->s_lvid_bh; | ||
2333 | struct logicalVolIntegrityDesc *lvid; | ||
2334 | |||
2335 | lvid = (struct logicalVolIntegrityDesc *)bh->b_data; | ||
2336 | udf_finalize_lvid(lvid); | ||
2337 | |||
2323 | /* | 2338 | /* |
2324 | * Blockdevice will be synced later so we don't have to submit | 2339 | * Blockdevice will be synced later so we don't have to submit |
2325 | * the buffer for IO | 2340 | * the buffer for IO |
2326 | */ | 2341 | */ |
2327 | mark_buffer_dirty(sbi->s_lvid_bh); | 2342 | mark_buffer_dirty(bh); |
2328 | sbi->s_lvid_dirty = 0; | 2343 | sbi->s_lvid_dirty = 0; |
2329 | } | 2344 | } |
2330 | mutex_unlock(&sbi->s_alloc_mutex); | 2345 | mutex_unlock(&sbi->s_alloc_mutex); |