Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
Pull UDF fixes and cleanups from Jan Kara: "Several small UDF fixes and cleanups and a small cleanup of fanotify code" * 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs: fanotify: simplify the code of fanotify_merge udf: simplify udf_ioctl() udf: fix ioctl errors udf: allow implicit blocksize specification during mount udf: check partition reference in udf_read_inode() udf: atomically read inode size udf: merge module informations in super.c udf: remove next_epos from udf_update_extent_cache() udf: Factor out trimming of crtime udf: remove empty condition udf: remove unneeded line break udf: merge bh free udf: use pointer for kernel_long_ad argument udf: use __packed instead of __attribute__ ((packed)) udf: Make stat on symlink report symlink length as st_size fs/udf: make #ifdef UDF_PREALLOCATE unconditional fs: udf: Replace CURRENT_TIME with current_time()
This commit is contained in:
commit
70fcf5c339
11 changed files with 205 additions and 193 deletions
|
@ -31,7 +31,6 @@ static bool should_merge(struct fsnotify_event *old_fsn,
|
||||||
static int fanotify_merge(struct list_head *list, struct fsnotify_event *event)
|
static int fanotify_merge(struct list_head *list, struct fsnotify_event *event)
|
||||||
{
|
{
|
||||||
struct fsnotify_event *test_event;
|
struct fsnotify_event *test_event;
|
||||||
bool do_merge = false;
|
|
||||||
|
|
||||||
pr_debug("%s: list=%p event=%p\n", __func__, list, event);
|
pr_debug("%s: list=%p event=%p\n", __func__, list, event);
|
||||||
|
|
||||||
|
@ -47,16 +46,12 @@ static int fanotify_merge(struct list_head *list, struct fsnotify_event *event)
|
||||||
|
|
||||||
list_for_each_entry_reverse(test_event, list, list) {
|
list_for_each_entry_reverse(test_event, list, list) {
|
||||||
if (should_merge(test_event, event)) {
|
if (should_merge(test_event, event)) {
|
||||||
do_merge = true;
|
test_event->mask |= event->mask;
|
||||||
break;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!do_merge)
|
return 0;
|
||||||
return 0;
|
|
||||||
|
|
||||||
test_event->mask |= event->mask;
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
|
#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
struct charspec {
|
struct charspec {
|
||||||
uint8_t charSetType;
|
uint8_t charSetType;
|
||||||
uint8_t charSetInfo[63];
|
uint8_t charSetInfo[63];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Character Set Type (ECMA 167r3 1/7.2.1.1) */
|
/* Character Set Type (ECMA 167r3 1/7.2.1.1) */
|
||||||
#define CHARSPEC_TYPE_CS0 0x00 /* (1/7.2.2) */
|
#define CHARSPEC_TYPE_CS0 0x00 /* (1/7.2.2) */
|
||||||
|
@ -68,7 +68,7 @@ struct timestamp {
|
||||||
uint8_t centiseconds;
|
uint8_t centiseconds;
|
||||||
uint8_t hundredsOfMicroseconds;
|
uint8_t hundredsOfMicroseconds;
|
||||||
uint8_t microseconds;
|
uint8_t microseconds;
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Type and Time Zone (ECMA 167r3 1/7.3.1) */
|
/* Type and Time Zone (ECMA 167r3 1/7.3.1) */
|
||||||
#define TIMESTAMP_TYPE_MASK 0xF000
|
#define TIMESTAMP_TYPE_MASK 0xF000
|
||||||
|
@ -82,7 +82,7 @@ struct regid {
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
uint8_t ident[23];
|
uint8_t ident[23];
|
||||||
uint8_t identSuffix[8];
|
uint8_t identSuffix[8];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Flags (ECMA 167r3 1/7.4.1) */
|
/* Flags (ECMA 167r3 1/7.4.1) */
|
||||||
#define ENTITYID_FLAGS_DIRTY 0x00
|
#define ENTITYID_FLAGS_DIRTY 0x00
|
||||||
|
@ -95,7 +95,7 @@ struct volStructDesc {
|
||||||
uint8_t stdIdent[VSD_STD_ID_LEN];
|
uint8_t stdIdent[VSD_STD_ID_LEN];
|
||||||
uint8_t structVersion;
|
uint8_t structVersion;
|
||||||
uint8_t structData[2041];
|
uint8_t structData[2041];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Standard Identifier (EMCA 167r2 2/9.1.2) */
|
/* Standard Identifier (EMCA 167r2 2/9.1.2) */
|
||||||
#define VSD_STD_ID_NSR02 "NSR02" /* (3/9.1) */
|
#define VSD_STD_ID_NSR02 "NSR02" /* (3/9.1) */
|
||||||
|
@ -114,7 +114,7 @@ struct beginningExtendedAreaDesc {
|
||||||
uint8_t stdIdent[VSD_STD_ID_LEN];
|
uint8_t stdIdent[VSD_STD_ID_LEN];
|
||||||
uint8_t structVersion;
|
uint8_t structVersion;
|
||||||
uint8_t structData[2041];
|
uint8_t structData[2041];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Terminating Extended Area Descriptor (ECMA 167r3 2/9.3) */
|
/* Terminating Extended Area Descriptor (ECMA 167r3 2/9.3) */
|
||||||
struct terminatingExtendedAreaDesc {
|
struct terminatingExtendedAreaDesc {
|
||||||
|
@ -122,7 +122,7 @@ struct terminatingExtendedAreaDesc {
|
||||||
uint8_t stdIdent[VSD_STD_ID_LEN];
|
uint8_t stdIdent[VSD_STD_ID_LEN];
|
||||||
uint8_t structVersion;
|
uint8_t structVersion;
|
||||||
uint8_t structData[2041];
|
uint8_t structData[2041];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Boot Descriptor (ECMA 167r3 2/9.4) */
|
/* Boot Descriptor (ECMA 167r3 2/9.4) */
|
||||||
struct bootDesc {
|
struct bootDesc {
|
||||||
|
@ -140,7 +140,7 @@ struct bootDesc {
|
||||||
__le16 flags;
|
__le16 flags;
|
||||||
uint8_t reserved2[32];
|
uint8_t reserved2[32];
|
||||||
uint8_t bootUse[1906];
|
uint8_t bootUse[1906];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Flags (ECMA 167r3 2/9.4.12) */
|
/* Flags (ECMA 167r3 2/9.4.12) */
|
||||||
#define BOOT_FLAGS_ERASE 0x01
|
#define BOOT_FLAGS_ERASE 0x01
|
||||||
|
@ -149,7 +149,7 @@ struct bootDesc {
|
||||||
struct extent_ad {
|
struct extent_ad {
|
||||||
__le32 extLength;
|
__le32 extLength;
|
||||||
__le32 extLocation;
|
__le32 extLocation;
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
struct kernel_extent_ad {
|
struct kernel_extent_ad {
|
||||||
uint32_t extLength;
|
uint32_t extLength;
|
||||||
|
@ -166,7 +166,7 @@ struct tag {
|
||||||
__le16 descCRC;
|
__le16 descCRC;
|
||||||
__le16 descCRCLength;
|
__le16 descCRCLength;
|
||||||
__le32 tagLocation;
|
__le32 tagLocation;
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Tag Identifier (ECMA 167r3 3/7.2.1) */
|
/* Tag Identifier (ECMA 167r3 3/7.2.1) */
|
||||||
#define TAG_IDENT_PVD 0x0001
|
#define TAG_IDENT_PVD 0x0001
|
||||||
|
@ -186,7 +186,7 @@ struct NSRDesc {
|
||||||
uint8_t structVersion;
|
uint8_t structVersion;
|
||||||
uint8_t reserved;
|
uint8_t reserved;
|
||||||
uint8_t structData[2040];
|
uint8_t structData[2040];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Primary Volume Descriptor (ECMA 167r3 3/10.1) */
|
/* Primary Volume Descriptor (ECMA 167r3 3/10.1) */
|
||||||
struct primaryVolDesc {
|
struct primaryVolDesc {
|
||||||
|
@ -212,7 +212,7 @@ struct primaryVolDesc {
|
||||||
__le32 predecessorVolDescSeqLocation;
|
__le32 predecessorVolDescSeqLocation;
|
||||||
__le16 flags;
|
__le16 flags;
|
||||||
uint8_t reserved[22];
|
uint8_t reserved[22];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Flags (ECMA 167r3 3/10.1.21) */
|
/* Flags (ECMA 167r3 3/10.1.21) */
|
||||||
#define PVD_FLAGS_VSID_COMMON 0x0001
|
#define PVD_FLAGS_VSID_COMMON 0x0001
|
||||||
|
@ -223,7 +223,7 @@ struct anchorVolDescPtr {
|
||||||
struct extent_ad mainVolDescSeqExt;
|
struct extent_ad mainVolDescSeqExt;
|
||||||
struct extent_ad reserveVolDescSeqExt;
|
struct extent_ad reserveVolDescSeqExt;
|
||||||
uint8_t reserved[480];
|
uint8_t reserved[480];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Volume Descriptor Pointer (ECMA 167r3 3/10.3) */
|
/* Volume Descriptor Pointer (ECMA 167r3 3/10.3) */
|
||||||
struct volDescPtr {
|
struct volDescPtr {
|
||||||
|
@ -231,7 +231,7 @@ struct volDescPtr {
|
||||||
__le32 volDescSeqNum;
|
__le32 volDescSeqNum;
|
||||||
struct extent_ad nextVolDescSeqExt;
|
struct extent_ad nextVolDescSeqExt;
|
||||||
uint8_t reserved[484];
|
uint8_t reserved[484];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Implementation Use Volume Descriptor (ECMA 167r3 3/10.4) */
|
/* Implementation Use Volume Descriptor (ECMA 167r3 3/10.4) */
|
||||||
struct impUseVolDesc {
|
struct impUseVolDesc {
|
||||||
|
@ -239,7 +239,7 @@ struct impUseVolDesc {
|
||||||
__le32 volDescSeqNum;
|
__le32 volDescSeqNum;
|
||||||
struct regid impIdent;
|
struct regid impIdent;
|
||||||
uint8_t impUse[460];
|
uint8_t impUse[460];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Partition Descriptor (ECMA 167r3 3/10.5) */
|
/* Partition Descriptor (ECMA 167r3 3/10.5) */
|
||||||
struct partitionDesc {
|
struct partitionDesc {
|
||||||
|
@ -255,7 +255,7 @@ struct partitionDesc {
|
||||||
struct regid impIdent;
|
struct regid impIdent;
|
||||||
uint8_t impUse[128];
|
uint8_t impUse[128];
|
||||||
uint8_t reserved[156];
|
uint8_t reserved[156];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Partition Flags (ECMA 167r3 3/10.5.3) */
|
/* Partition Flags (ECMA 167r3 3/10.5.3) */
|
||||||
#define PD_PARTITION_FLAGS_ALLOC 0x0001
|
#define PD_PARTITION_FLAGS_ALLOC 0x0001
|
||||||
|
@ -291,14 +291,14 @@ struct logicalVolDesc {
|
||||||
uint8_t impUse[128];
|
uint8_t impUse[128];
|
||||||
struct extent_ad integritySeqExt;
|
struct extent_ad integritySeqExt;
|
||||||
uint8_t partitionMaps[0];
|
uint8_t partitionMaps[0];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Generic Partition Map (ECMA 167r3 3/10.7.1) */
|
/* Generic Partition Map (ECMA 167r3 3/10.7.1) */
|
||||||
struct genericPartitionMap {
|
struct genericPartitionMap {
|
||||||
uint8_t partitionMapType;
|
uint8_t partitionMapType;
|
||||||
uint8_t partitionMapLength;
|
uint8_t partitionMapLength;
|
||||||
uint8_t partitionMapping[0];
|
uint8_t partitionMapping[0];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Partition Map Type (ECMA 167r3 3/10.7.1.1) */
|
/* Partition Map Type (ECMA 167r3 3/10.7.1.1) */
|
||||||
#define GP_PARTITION_MAP_TYPE_UNDEF 0x00
|
#define GP_PARTITION_MAP_TYPE_UNDEF 0x00
|
||||||
|
@ -311,14 +311,14 @@ struct genericPartitionMap1 {
|
||||||
uint8_t partitionMapLength;
|
uint8_t partitionMapLength;
|
||||||
__le16 volSeqNum;
|
__le16 volSeqNum;
|
||||||
__le16 partitionNum;
|
__le16 partitionNum;
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Type 2 Partition Map (ECMA 167r3 3/10.7.3) */
|
/* Type 2 Partition Map (ECMA 167r3 3/10.7.3) */
|
||||||
struct genericPartitionMap2 {
|
struct genericPartitionMap2 {
|
||||||
uint8_t partitionMapType;
|
uint8_t partitionMapType;
|
||||||
uint8_t partitionMapLength;
|
uint8_t partitionMapLength;
|
||||||
uint8_t partitionIdent[62];
|
uint8_t partitionIdent[62];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Unallocated Space Descriptor (ECMA 167r3 3/10.8) */
|
/* Unallocated Space Descriptor (ECMA 167r3 3/10.8) */
|
||||||
struct unallocSpaceDesc {
|
struct unallocSpaceDesc {
|
||||||
|
@ -326,13 +326,13 @@ struct unallocSpaceDesc {
|
||||||
__le32 volDescSeqNum;
|
__le32 volDescSeqNum;
|
||||||
__le32 numAllocDescs;
|
__le32 numAllocDescs;
|
||||||
struct extent_ad allocDescs[0];
|
struct extent_ad allocDescs[0];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Terminating Descriptor (ECMA 167r3 3/10.9) */
|
/* Terminating Descriptor (ECMA 167r3 3/10.9) */
|
||||||
struct terminatingDesc {
|
struct terminatingDesc {
|
||||||
struct tag descTag;
|
struct tag descTag;
|
||||||
uint8_t reserved[496];
|
uint8_t reserved[496];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Logical Volume Integrity Descriptor (ECMA 167r3 3/10.10) */
|
/* Logical Volume Integrity Descriptor (ECMA 167r3 3/10.10) */
|
||||||
struct logicalVolIntegrityDesc {
|
struct logicalVolIntegrityDesc {
|
||||||
|
@ -346,7 +346,7 @@ struct logicalVolIntegrityDesc {
|
||||||
__le32 freeSpaceTable[0];
|
__le32 freeSpaceTable[0];
|
||||||
__le32 sizeTable[0];
|
__le32 sizeTable[0];
|
||||||
uint8_t impUse[0];
|
uint8_t impUse[0];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Integrity Type (ECMA 167r3 3/10.10.3) */
|
/* Integrity Type (ECMA 167r3 3/10.10.3) */
|
||||||
#define LVID_INTEGRITY_TYPE_OPEN 0x00000000
|
#define LVID_INTEGRITY_TYPE_OPEN 0x00000000
|
||||||
|
@ -356,7 +356,7 @@ struct logicalVolIntegrityDesc {
|
||||||
struct lb_addr {
|
struct lb_addr {
|
||||||
__le32 logicalBlockNum;
|
__le32 logicalBlockNum;
|
||||||
__le16 partitionReferenceNum;
|
__le16 partitionReferenceNum;
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* ... and its in-core analog */
|
/* ... and its in-core analog */
|
||||||
struct kernel_lb_addr {
|
struct kernel_lb_addr {
|
||||||
|
@ -368,14 +368,14 @@ struct kernel_lb_addr {
|
||||||
struct short_ad {
|
struct short_ad {
|
||||||
__le32 extLength;
|
__le32 extLength;
|
||||||
__le32 extPosition;
|
__le32 extPosition;
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Long Allocation Descriptor (ECMA 167r3 4/14.14.2) */
|
/* Long Allocation Descriptor (ECMA 167r3 4/14.14.2) */
|
||||||
struct long_ad {
|
struct long_ad {
|
||||||
__le32 extLength;
|
__le32 extLength;
|
||||||
struct lb_addr extLocation;
|
struct lb_addr extLocation;
|
||||||
uint8_t impUse[6];
|
uint8_t impUse[6];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
struct kernel_long_ad {
|
struct kernel_long_ad {
|
||||||
uint32_t extLength;
|
uint32_t extLength;
|
||||||
|
@ -389,7 +389,7 @@ struct ext_ad {
|
||||||
__le32 recordedLength;
|
__le32 recordedLength;
|
||||||
__le32 informationLength;
|
__le32 informationLength;
|
||||||
struct lb_addr extLocation;
|
struct lb_addr extLocation;
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
struct kernel_ext_ad {
|
struct kernel_ext_ad {
|
||||||
uint32_t extLength;
|
uint32_t extLength;
|
||||||
|
@ -434,7 +434,7 @@ struct fileSetDesc {
|
||||||
struct long_ad nextExt;
|
struct long_ad nextExt;
|
||||||
struct long_ad streamDirectoryICB;
|
struct long_ad streamDirectoryICB;
|
||||||
uint8_t reserved[32];
|
uint8_t reserved[32];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Partition Header Descriptor (ECMA 167r3 4/14.3) */
|
/* Partition Header Descriptor (ECMA 167r3 4/14.3) */
|
||||||
struct partitionHeaderDesc {
|
struct partitionHeaderDesc {
|
||||||
|
@ -444,7 +444,7 @@ struct partitionHeaderDesc {
|
||||||
struct short_ad freedSpaceTable;
|
struct short_ad freedSpaceTable;
|
||||||
struct short_ad freedSpaceBitmap;
|
struct short_ad freedSpaceBitmap;
|
||||||
uint8_t reserved[88];
|
uint8_t reserved[88];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* File Identifier Descriptor (ECMA 167r3 4/14.4) */
|
/* File Identifier Descriptor (ECMA 167r3 4/14.4) */
|
||||||
struct fileIdentDesc {
|
struct fileIdentDesc {
|
||||||
|
@ -457,7 +457,7 @@ struct fileIdentDesc {
|
||||||
uint8_t impUse[0];
|
uint8_t impUse[0];
|
||||||
uint8_t fileIdent[0];
|
uint8_t fileIdent[0];
|
||||||
uint8_t padding[0];
|
uint8_t padding[0];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* File Characteristics (ECMA 167r3 4/14.4.3) */
|
/* File Characteristics (ECMA 167r3 4/14.4.3) */
|
||||||
#define FID_FILE_CHAR_HIDDEN 0x01
|
#define FID_FILE_CHAR_HIDDEN 0x01
|
||||||
|
@ -471,7 +471,7 @@ struct allocExtDesc {
|
||||||
struct tag descTag;
|
struct tag descTag;
|
||||||
__le32 previousAllocExtLocation;
|
__le32 previousAllocExtLocation;
|
||||||
__le32 lengthAllocDescs;
|
__le32 lengthAllocDescs;
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* ICB Tag (ECMA 167r3 4/14.6) */
|
/* ICB Tag (ECMA 167r3 4/14.6) */
|
||||||
struct icbtag {
|
struct icbtag {
|
||||||
|
@ -483,7 +483,7 @@ struct icbtag {
|
||||||
uint8_t fileType;
|
uint8_t fileType;
|
||||||
struct lb_addr parentICBLocation;
|
struct lb_addr parentICBLocation;
|
||||||
__le16 flags;
|
__le16 flags;
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Strategy Type (ECMA 167r3 4/14.6.2) */
|
/* Strategy Type (ECMA 167r3 4/14.6.2) */
|
||||||
#define ICBTAG_STRATEGY_TYPE_UNDEF 0x0000
|
#define ICBTAG_STRATEGY_TYPE_UNDEF 0x0000
|
||||||
|
@ -531,13 +531,13 @@ struct indirectEntry {
|
||||||
struct tag descTag;
|
struct tag descTag;
|
||||||
struct icbtag icbTag;
|
struct icbtag icbTag;
|
||||||
struct long_ad indirectICB;
|
struct long_ad indirectICB;
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Terminal Entry (ECMA 167r3 4/14.8) */
|
/* Terminal Entry (ECMA 167r3 4/14.8) */
|
||||||
struct terminalEntry {
|
struct terminalEntry {
|
||||||
struct tag descTag;
|
struct tag descTag;
|
||||||
struct icbtag icbTag;
|
struct icbtag icbTag;
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* File Entry (ECMA 167r3 4/14.9) */
|
/* File Entry (ECMA 167r3 4/14.9) */
|
||||||
struct fileEntry {
|
struct fileEntry {
|
||||||
|
@ -563,7 +563,7 @@ struct fileEntry {
|
||||||
__le32 lengthAllocDescs;
|
__le32 lengthAllocDescs;
|
||||||
uint8_t extendedAttr[0];
|
uint8_t extendedAttr[0];
|
||||||
uint8_t allocDescs[0];
|
uint8_t allocDescs[0];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Permissions (ECMA 167r3 4/14.9.5) */
|
/* Permissions (ECMA 167r3 4/14.9.5) */
|
||||||
#define FE_PERM_O_EXEC 0x00000001U
|
#define FE_PERM_O_EXEC 0x00000001U
|
||||||
|
@ -607,7 +607,7 @@ struct extendedAttrHeaderDesc {
|
||||||
struct tag descTag;
|
struct tag descTag;
|
||||||
__le32 impAttrLocation;
|
__le32 impAttrLocation;
|
||||||
__le32 appAttrLocation;
|
__le32 appAttrLocation;
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Generic Format (ECMA 167r3 4/14.10.2) */
|
/* Generic Format (ECMA 167r3 4/14.10.2) */
|
||||||
struct genericFormat {
|
struct genericFormat {
|
||||||
|
@ -616,7 +616,7 @@ struct genericFormat {
|
||||||
uint8_t reserved[3];
|
uint8_t reserved[3];
|
||||||
__le32 attrLength;
|
__le32 attrLength;
|
||||||
uint8_t attrData[0];
|
uint8_t attrData[0];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Character Set Information (ECMA 167r3 4/14.10.3) */
|
/* Character Set Information (ECMA 167r3 4/14.10.3) */
|
||||||
struct charSetInfo {
|
struct charSetInfo {
|
||||||
|
@ -627,7 +627,7 @@ struct charSetInfo {
|
||||||
__le32 escapeSeqLength;
|
__le32 escapeSeqLength;
|
||||||
uint8_t charSetType;
|
uint8_t charSetType;
|
||||||
uint8_t escapeSeq[0];
|
uint8_t escapeSeq[0];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Alternate Permissions (ECMA 167r3 4/14.10.4) */
|
/* Alternate Permissions (ECMA 167r3 4/14.10.4) */
|
||||||
struct altPerms {
|
struct altPerms {
|
||||||
|
@ -638,7 +638,7 @@ struct altPerms {
|
||||||
__le16 ownerIdent;
|
__le16 ownerIdent;
|
||||||
__le16 groupIdent;
|
__le16 groupIdent;
|
||||||
__le16 permission;
|
__le16 permission;
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* File Times Extended Attribute (ECMA 167r3 4/14.10.5) */
|
/* File Times Extended Attribute (ECMA 167r3 4/14.10.5) */
|
||||||
struct fileTimesExtAttr {
|
struct fileTimesExtAttr {
|
||||||
|
@ -649,7 +649,7 @@ struct fileTimesExtAttr {
|
||||||
__le32 dataLength;
|
__le32 dataLength;
|
||||||
__le32 fileTimeExistence;
|
__le32 fileTimeExistence;
|
||||||
uint8_t fileTimes;
|
uint8_t fileTimes;
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* FileTimeExistence (ECMA 167r3 4/14.10.5.6) */
|
/* FileTimeExistence (ECMA 167r3 4/14.10.5.6) */
|
||||||
#define FTE_CREATION 0x00000001
|
#define FTE_CREATION 0x00000001
|
||||||
|
@ -666,7 +666,7 @@ struct infoTimesExtAttr {
|
||||||
__le32 dataLength;
|
__le32 dataLength;
|
||||||
__le32 infoTimeExistence;
|
__le32 infoTimeExistence;
|
||||||
uint8_t infoTimes[0];
|
uint8_t infoTimes[0];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Device Specification (ECMA 167r3 4/14.10.7) */
|
/* Device Specification (ECMA 167r3 4/14.10.7) */
|
||||||
struct deviceSpec {
|
struct deviceSpec {
|
||||||
|
@ -678,7 +678,7 @@ struct deviceSpec {
|
||||||
__le32 majorDeviceIdent;
|
__le32 majorDeviceIdent;
|
||||||
__le32 minorDeviceIdent;
|
__le32 minorDeviceIdent;
|
||||||
uint8_t impUse[0];
|
uint8_t impUse[0];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Implementation Use Extended Attr (ECMA 167r3 4/14.10.8) */
|
/* Implementation Use Extended Attr (ECMA 167r3 4/14.10.8) */
|
||||||
struct impUseExtAttr {
|
struct impUseExtAttr {
|
||||||
|
@ -689,7 +689,7 @@ struct impUseExtAttr {
|
||||||
__le32 impUseLength;
|
__le32 impUseLength;
|
||||||
struct regid impIdent;
|
struct regid impIdent;
|
||||||
uint8_t impUse[0];
|
uint8_t impUse[0];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Application Use Extended Attribute (ECMA 167r3 4/14.10.9) */
|
/* Application Use Extended Attribute (ECMA 167r3 4/14.10.9) */
|
||||||
struct appUseExtAttr {
|
struct appUseExtAttr {
|
||||||
|
@ -700,7 +700,7 @@ struct appUseExtAttr {
|
||||||
__le32 appUseLength;
|
__le32 appUseLength;
|
||||||
struct regid appIdent;
|
struct regid appIdent;
|
||||||
uint8_t appUse[0];
|
uint8_t appUse[0];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
#define EXTATTR_CHAR_SET 1
|
#define EXTATTR_CHAR_SET 1
|
||||||
#define EXTATTR_ALT_PERMS 3
|
#define EXTATTR_ALT_PERMS 3
|
||||||
|
@ -716,7 +716,7 @@ struct unallocSpaceEntry {
|
||||||
struct icbtag icbTag;
|
struct icbtag icbTag;
|
||||||
__le32 lengthAllocDescs;
|
__le32 lengthAllocDescs;
|
||||||
uint8_t allocDescs[0];
|
uint8_t allocDescs[0];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Space Bitmap Descriptor (ECMA 167r3 4/14.12) */
|
/* Space Bitmap Descriptor (ECMA 167r3 4/14.12) */
|
||||||
struct spaceBitmapDesc {
|
struct spaceBitmapDesc {
|
||||||
|
@ -724,7 +724,7 @@ struct spaceBitmapDesc {
|
||||||
__le32 numOfBits;
|
__le32 numOfBits;
|
||||||
__le32 numOfBytes;
|
__le32 numOfBytes;
|
||||||
uint8_t bitmap[0];
|
uint8_t bitmap[0];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Partition Integrity Entry (ECMA 167r3 4/14.13) */
|
/* Partition Integrity Entry (ECMA 167r3 4/14.13) */
|
||||||
struct partitionIntegrityEntry {
|
struct partitionIntegrityEntry {
|
||||||
|
@ -735,7 +735,7 @@ struct partitionIntegrityEntry {
|
||||||
uint8_t reserved[175];
|
uint8_t reserved[175];
|
||||||
struct regid impIdent;
|
struct regid impIdent;
|
||||||
uint8_t impUse[256];
|
uint8_t impUse[256];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Short Allocation Descriptor (ECMA 167r3 4/14.14.1) */
|
/* Short Allocation Descriptor (ECMA 167r3 4/14.14.1) */
|
||||||
|
|
||||||
|
@ -753,7 +753,7 @@ struct partitionIntegrityEntry {
|
||||||
struct logicalVolHeaderDesc {
|
struct logicalVolHeaderDesc {
|
||||||
__le64 uniqueID;
|
__le64 uniqueID;
|
||||||
uint8_t reserved[24];
|
uint8_t reserved[24];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Path Component (ECMA 167r3 4/14.16.1) */
|
/* Path Component (ECMA 167r3 4/14.16.1) */
|
||||||
struct pathComponent {
|
struct pathComponent {
|
||||||
|
@ -761,7 +761,7 @@ struct pathComponent {
|
||||||
uint8_t lengthComponentIdent;
|
uint8_t lengthComponentIdent;
|
||||||
__le16 componentFileVersionNum;
|
__le16 componentFileVersionNum;
|
||||||
dstring componentIdent[0];
|
dstring componentIdent[0];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* File Entry (ECMA 167r3 4/14.17) */
|
/* File Entry (ECMA 167r3 4/14.17) */
|
||||||
struct extendedFileEntry {
|
struct extendedFileEntry {
|
||||||
|
@ -791,6 +791,6 @@ struct extendedFileEntry {
|
||||||
__le32 lengthAllocDescs;
|
__le32 lengthAllocDescs;
|
||||||
uint8_t extendedAttr[0];
|
uint8_t extendedAttr[0];
|
||||||
uint8_t allocDescs[0];
|
uint8_t allocDescs[0];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
#endif /* _ECMA_167_H */
|
#endif /* _ECMA_167_H */
|
||||||
|
|
|
@ -176,54 +176,46 @@ long udf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
||||||
{
|
{
|
||||||
struct inode *inode = file_inode(filp);
|
struct inode *inode = file_inode(filp);
|
||||||
long old_block, new_block;
|
long old_block, new_block;
|
||||||
int result = -EINVAL;
|
int result;
|
||||||
|
|
||||||
if (inode_permission(inode, MAY_READ) != 0) {
|
if (inode_permission(inode, MAY_READ) != 0) {
|
||||||
udf_debug("no permission to access inode %lu\n", inode->i_ino);
|
udf_debug("no permission to access inode %lu\n", inode->i_ino);
|
||||||
result = -EPERM;
|
return -EPERM;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!arg) {
|
if (!arg && ((cmd == UDF_GETVOLIDENT) || (cmd == UDF_GETEASIZE) ||
|
||||||
|
(cmd == UDF_RELOCATE_BLOCKS) || (cmd == UDF_GETEABLOCK))) {
|
||||||
udf_debug("invalid argument to udf_ioctl\n");
|
udf_debug("invalid argument to udf_ioctl\n");
|
||||||
result = -EINVAL;
|
return -EINVAL;
|
||||||
goto out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case UDF_GETVOLIDENT:
|
case UDF_GETVOLIDENT:
|
||||||
if (copy_to_user((char __user *)arg,
|
if (copy_to_user((char __user *)arg,
|
||||||
UDF_SB(inode->i_sb)->s_volume_ident, 32))
|
UDF_SB(inode->i_sb)->s_volume_ident, 32))
|
||||||
result = -EFAULT;
|
return -EFAULT;
|
||||||
else
|
return 0;
|
||||||
result = 0;
|
|
||||||
goto out;
|
|
||||||
case UDF_RELOCATE_BLOCKS:
|
case UDF_RELOCATE_BLOCKS:
|
||||||
if (!capable(CAP_SYS_ADMIN)) {
|
if (!capable(CAP_SYS_ADMIN))
|
||||||
result = -EPERM;
|
return -EPERM;
|
||||||
goto out;
|
if (get_user(old_block, (long __user *)arg))
|
||||||
}
|
return -EFAULT;
|
||||||
if (get_user(old_block, (long __user *)arg)) {
|
|
||||||
result = -EFAULT;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
result = udf_relocate_blocks(inode->i_sb,
|
result = udf_relocate_blocks(inode->i_sb,
|
||||||
old_block, &new_block);
|
old_block, &new_block);
|
||||||
if (result == 0)
|
if (result == 0)
|
||||||
result = put_user(new_block, (long __user *)arg);
|
result = put_user(new_block, (long __user *)arg);
|
||||||
goto out;
|
return result;
|
||||||
case UDF_GETEASIZE:
|
case UDF_GETEASIZE:
|
||||||
result = put_user(UDF_I(inode)->i_lenEAttr, (int __user *)arg);
|
return put_user(UDF_I(inode)->i_lenEAttr, (int __user *)arg);
|
||||||
goto out;
|
|
||||||
case UDF_GETEABLOCK:
|
case UDF_GETEABLOCK:
|
||||||
result = copy_to_user((char __user *)arg,
|
return copy_to_user((char __user *)arg,
|
||||||
UDF_I(inode)->i_ext.i_data,
|
UDF_I(inode)->i_ext.i_data,
|
||||||
UDF_I(inode)->i_lenEAttr) ? -EFAULT : 0;
|
UDF_I(inode)->i_lenEAttr) ? -EFAULT : 0;
|
||||||
goto out;
|
default:
|
||||||
|
return -ENOIOCTLCMD;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
return 0;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int udf_release_file(struct inode *inode, struct file *filp)
|
static int udf_release_file(struct inode *inode, struct file *filp)
|
||||||
|
|
118
fs/udf/inode.c
118
fs/udf/inode.c
|
@ -43,10 +43,6 @@
|
||||||
#include "udf_i.h"
|
#include "udf_i.h"
|
||||||
#include "udf_sb.h"
|
#include "udf_sb.h"
|
||||||
|
|
||||||
MODULE_AUTHOR("Ben Fennema");
|
|
||||||
MODULE_DESCRIPTION("Universal Disk Format Filesystem");
|
|
||||||
MODULE_LICENSE("GPL");
|
|
||||||
|
|
||||||
#define EXTENT_MERGE_SIZE 5
|
#define EXTENT_MERGE_SIZE 5
|
||||||
|
|
||||||
static umode_t udf_convert_permissions(struct fileEntry *);
|
static umode_t udf_convert_permissions(struct fileEntry *);
|
||||||
|
@ -57,14 +53,12 @@ static sector_t inode_getblk(struct inode *, sector_t, int *, int *);
|
||||||
static int8_t udf_insert_aext(struct inode *, struct extent_position,
|
static int8_t udf_insert_aext(struct inode *, struct extent_position,
|
||||||
struct kernel_lb_addr, uint32_t);
|
struct kernel_lb_addr, uint32_t);
|
||||||
static void udf_split_extents(struct inode *, int *, int, int,
|
static void udf_split_extents(struct inode *, int *, int, int,
|
||||||
struct kernel_long_ad[EXTENT_MERGE_SIZE], int *);
|
struct kernel_long_ad *, int *);
|
||||||
static void udf_prealloc_extents(struct inode *, int, int,
|
static void udf_prealloc_extents(struct inode *, int, int,
|
||||||
struct kernel_long_ad[EXTENT_MERGE_SIZE], int *);
|
struct kernel_long_ad *, int *);
|
||||||
static void udf_merge_extents(struct inode *,
|
static void udf_merge_extents(struct inode *, struct kernel_long_ad *, int *);
|
||||||
struct kernel_long_ad[EXTENT_MERGE_SIZE], int *);
|
static void udf_update_extents(struct inode *, struct kernel_long_ad *, int,
|
||||||
static void udf_update_extents(struct inode *,
|
int, struct extent_position *);
|
||||||
struct kernel_long_ad[EXTENT_MERGE_SIZE], int, int,
|
|
||||||
struct extent_position *);
|
|
||||||
static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
|
static int udf_get_block(struct inode *, sector_t, struct buffer_head *, int);
|
||||||
|
|
||||||
static void __udf_clear_extent_cache(struct inode *inode)
|
static void __udf_clear_extent_cache(struct inode *inode)
|
||||||
|
@ -111,7 +105,7 @@ static int udf_read_extent_cache(struct inode *inode, loff_t bcount,
|
||||||
|
|
||||||
/* Add extent to extent cache */
|
/* Add extent to extent cache */
|
||||||
static void udf_update_extent_cache(struct inode *inode, loff_t estart,
|
static void udf_update_extent_cache(struct inode *inode, loff_t estart,
|
||||||
struct extent_position *pos, int next_epos)
|
struct extent_position *pos)
|
||||||
{
|
{
|
||||||
struct udf_inode_info *iinfo = UDF_I(inode);
|
struct udf_inode_info *iinfo = UDF_I(inode);
|
||||||
|
|
||||||
|
@ -120,19 +114,16 @@ static void udf_update_extent_cache(struct inode *inode, loff_t estart,
|
||||||
__udf_clear_extent_cache(inode);
|
__udf_clear_extent_cache(inode);
|
||||||
if (pos->bh)
|
if (pos->bh)
|
||||||
get_bh(pos->bh);
|
get_bh(pos->bh);
|
||||||
memcpy(&iinfo->cached_extent.epos, pos,
|
memcpy(&iinfo->cached_extent.epos, pos, sizeof(struct extent_position));
|
||||||
sizeof(struct extent_position));
|
|
||||||
iinfo->cached_extent.lstart = estart;
|
iinfo->cached_extent.lstart = estart;
|
||||||
if (next_epos)
|
switch (iinfo->i_alloc_type) {
|
||||||
switch (iinfo->i_alloc_type) {
|
case ICBTAG_FLAG_AD_SHORT:
|
||||||
case ICBTAG_FLAG_AD_SHORT:
|
iinfo->cached_extent.epos.offset -= sizeof(struct short_ad);
|
||||||
iinfo->cached_extent.epos.offset -=
|
break;
|
||||||
sizeof(struct short_ad);
|
case ICBTAG_FLAG_AD_LONG:
|
||||||
break;
|
iinfo->cached_extent.epos.offset -= sizeof(struct long_ad);
|
||||||
case ICBTAG_FLAG_AD_LONG:
|
break;
|
||||||
iinfo->cached_extent.epos.offset -=
|
}
|
||||||
sizeof(struct long_ad);
|
|
||||||
}
|
|
||||||
spin_unlock(&iinfo->i_extent_cache_lock);
|
spin_unlock(&iinfo->i_extent_cache_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -747,11 +738,8 @@ static sector_t inode_getblk(struct inode *inode, sector_t block,
|
||||||
~(inode->i_sb->s_blocksize - 1));
|
~(inode->i_sb->s_blocksize - 1));
|
||||||
udf_write_aext(inode, &cur_epos, &eloc, elen, 1);
|
udf_write_aext(inode, &cur_epos, &eloc, elen, 1);
|
||||||
}
|
}
|
||||||
brelse(prev_epos.bh);
|
|
||||||
brelse(cur_epos.bh);
|
|
||||||
brelse(next_epos.bh);
|
|
||||||
newblock = udf_get_lb_pblock(inode->i_sb, &eloc, offset);
|
newblock = udf_get_lb_pblock(inode->i_sb, &eloc, offset);
|
||||||
return newblock;
|
goto out_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Are we beyond EOF? */
|
/* Are we beyond EOF? */
|
||||||
|
@ -774,11 +762,9 @@ static sector_t inode_getblk(struct inode *inode, sector_t block,
|
||||||
/* Create extents for the hole between EOF and offset */
|
/* Create extents for the hole between EOF and offset */
|
||||||
ret = udf_do_extend_file(inode, &prev_epos, laarr, offset);
|
ret = udf_do_extend_file(inode, &prev_epos, laarr, offset);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
brelse(prev_epos.bh);
|
|
||||||
brelse(cur_epos.bh);
|
|
||||||
brelse(next_epos.bh);
|
|
||||||
*err = ret;
|
*err = ret;
|
||||||
return 0;
|
newblock = 0;
|
||||||
|
goto out_free;
|
||||||
}
|
}
|
||||||
c = 0;
|
c = 0;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
|
@ -841,11 +827,9 @@ static sector_t inode_getblk(struct inode *inode, sector_t block,
|
||||||
iinfo->i_location.partitionReferenceNum,
|
iinfo->i_location.partitionReferenceNum,
|
||||||
goal, err);
|
goal, err);
|
||||||
if (!newblocknum) {
|
if (!newblocknum) {
|
||||||
brelse(prev_epos.bh);
|
|
||||||
brelse(cur_epos.bh);
|
|
||||||
brelse(next_epos.bh);
|
|
||||||
*err = -ENOSPC;
|
*err = -ENOSPC;
|
||||||
return 0;
|
newblock = 0;
|
||||||
|
goto out_free;
|
||||||
}
|
}
|
||||||
if (isBeyondEOF)
|
if (isBeyondEOF)
|
||||||
iinfo->i_lenExtents += inode->i_sb->s_blocksize;
|
iinfo->i_lenExtents += inode->i_sb->s_blocksize;
|
||||||
|
@ -857,14 +841,12 @@ static sector_t inode_getblk(struct inode *inode, sector_t block,
|
||||||
* block */
|
* block */
|
||||||
udf_split_extents(inode, &c, offset, newblocknum, laarr, &endnum);
|
udf_split_extents(inode, &c, offset, newblocknum, laarr, &endnum);
|
||||||
|
|
||||||
#ifdef UDF_PREALLOCATE
|
|
||||||
/* We preallocate blocks only for regular files. It also makes sense
|
/* We preallocate blocks only for regular files. It also makes sense
|
||||||
* for directories but there's a problem when to drop the
|
* for directories but there's a problem when to drop the
|
||||||
* preallocation. We might use some delayed work for that but I feel
|
* preallocation. We might use some delayed work for that but I feel
|
||||||
* it's overengineering for a filesystem like UDF. */
|
* it's overengineering for a filesystem like UDF. */
|
||||||
if (S_ISREG(inode->i_mode))
|
if (S_ISREG(inode->i_mode))
|
||||||
udf_prealloc_extents(inode, c, lastblock, laarr, &endnum);
|
udf_prealloc_extents(inode, c, lastblock, laarr, &endnum);
|
||||||
#endif
|
|
||||||
|
|
||||||
/* merge any continuous blocks in laarr */
|
/* merge any continuous blocks in laarr */
|
||||||
udf_merge_extents(inode, laarr, &endnum);
|
udf_merge_extents(inode, laarr, &endnum);
|
||||||
|
@ -874,15 +856,11 @@ static sector_t inode_getblk(struct inode *inode, sector_t block,
|
||||||
* the new number of extents is less than the old number */
|
* the new number of extents is less than the old number */
|
||||||
udf_update_extents(inode, laarr, startnum, endnum, &prev_epos);
|
udf_update_extents(inode, laarr, startnum, endnum, &prev_epos);
|
||||||
|
|
||||||
brelse(prev_epos.bh);
|
|
||||||
brelse(cur_epos.bh);
|
|
||||||
brelse(next_epos.bh);
|
|
||||||
|
|
||||||
newblock = udf_get_pblock(inode->i_sb, newblocknum,
|
newblock = udf_get_pblock(inode->i_sb, newblocknum,
|
||||||
iinfo->i_location.partitionReferenceNum, 0);
|
iinfo->i_location.partitionReferenceNum, 0);
|
||||||
if (!newblock) {
|
if (!newblock) {
|
||||||
*err = -EIO;
|
*err = -EIO;
|
||||||
return 0;
|
goto out_free;
|
||||||
}
|
}
|
||||||
*new = 1;
|
*new = 1;
|
||||||
iinfo->i_next_alloc_block = block;
|
iinfo->i_next_alloc_block = block;
|
||||||
|
@ -893,13 +871,15 @@ static sector_t inode_getblk(struct inode *inode, sector_t block,
|
||||||
udf_sync_inode(inode);
|
udf_sync_inode(inode);
|
||||||
else
|
else
|
||||||
mark_inode_dirty(inode);
|
mark_inode_dirty(inode);
|
||||||
|
out_free:
|
||||||
|
brelse(prev_epos.bh);
|
||||||
|
brelse(cur_epos.bh);
|
||||||
|
brelse(next_epos.bh);
|
||||||
return newblock;
|
return newblock;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void udf_split_extents(struct inode *inode, int *c, int offset,
|
static void udf_split_extents(struct inode *inode, int *c, int offset,
|
||||||
int newblocknum,
|
int newblocknum, struct kernel_long_ad *laarr,
|
||||||
struct kernel_long_ad laarr[EXTENT_MERGE_SIZE],
|
|
||||||
int *endnum)
|
int *endnum)
|
||||||
{
|
{
|
||||||
unsigned long blocksize = inode->i_sb->s_blocksize;
|
unsigned long blocksize = inode->i_sb->s_blocksize;
|
||||||
|
@ -963,7 +943,7 @@ static void udf_split_extents(struct inode *inode, int *c, int offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,
|
static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,
|
||||||
struct kernel_long_ad laarr[EXTENT_MERGE_SIZE],
|
struct kernel_long_ad *laarr,
|
||||||
int *endnum)
|
int *endnum)
|
||||||
{
|
{
|
||||||
int start, length = 0, currlength = 0, i;
|
int start, length = 0, currlength = 0, i;
|
||||||
|
@ -1058,8 +1038,7 @@ static void udf_prealloc_extents(struct inode *inode, int c, int lastblock,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void udf_merge_extents(struct inode *inode,
|
static void udf_merge_extents(struct inode *inode, struct kernel_long_ad *laarr,
|
||||||
struct kernel_long_ad laarr[EXTENT_MERGE_SIZE],
|
|
||||||
int *endnum)
|
int *endnum)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -1158,8 +1137,7 @@ static void udf_merge_extents(struct inode *inode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void udf_update_extents(struct inode *inode,
|
static void udf_update_extents(struct inode *inode, struct kernel_long_ad *laarr,
|
||||||
struct kernel_long_ad laarr[EXTENT_MERGE_SIZE],
|
|
||||||
int startnum, int endnum,
|
int startnum, int endnum,
|
||||||
struct extent_position *epos)
|
struct extent_position *epos)
|
||||||
{
|
{
|
||||||
|
@ -1299,6 +1277,12 @@ static int udf_read_inode(struct inode *inode, bool hidden_inode)
|
||||||
int ret = -EIO;
|
int ret = -EIO;
|
||||||
|
|
||||||
reread:
|
reread:
|
||||||
|
if (iloc->partitionReferenceNum >= sbi->s_partitions) {
|
||||||
|
udf_debug("partition reference: %d > logical volume partitions: %d\n",
|
||||||
|
iloc->partitionReferenceNum, sbi->s_partitions);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
if (iloc->logicalBlockNum >=
|
if (iloc->logicalBlockNum >=
|
||||||
sbi->s_partmaps[iloc->partitionReferenceNum].s_partition_len) {
|
sbi->s_partmaps[iloc->partitionReferenceNum].s_partition_len) {
|
||||||
udf_debug("block=%d, partition=%d out of range\n",
|
udf_debug("block=%d, partition=%d out of range\n",
|
||||||
|
@ -1549,7 +1533,7 @@ static int udf_read_inode(struct inode *inode, bool hidden_inode)
|
||||||
break;
|
break;
|
||||||
case ICBTAG_FILE_TYPE_SYMLINK:
|
case ICBTAG_FILE_TYPE_SYMLINK:
|
||||||
inode->i_data.a_ops = &udf_symlink_aops;
|
inode->i_data.a_ops = &udf_symlink_aops;
|
||||||
inode->i_op = &page_symlink_inode_operations;
|
inode->i_op = &udf_symlink_inode_operations;
|
||||||
inode_nohighmem(inode);
|
inode_nohighmem(inode);
|
||||||
inode->i_mode = S_IFLNK | S_IRWXUGO;
|
inode->i_mode = S_IFLNK | S_IRWXUGO;
|
||||||
break;
|
break;
|
||||||
|
@ -1627,6 +1611,14 @@ static int udf_sync_inode(struct inode *inode)
|
||||||
return udf_update_inode(inode, 1);
|
return udf_update_inode(inode, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void udf_adjust_time(struct udf_inode_info *iinfo, struct timespec time)
|
||||||
|
{
|
||||||
|
if (iinfo->i_crtime.tv_sec > time.tv_sec ||
|
||||||
|
(iinfo->i_crtime.tv_sec == time.tv_sec &&
|
||||||
|
iinfo->i_crtime.tv_nsec > time.tv_nsec))
|
||||||
|
iinfo->i_crtime = time;
|
||||||
|
}
|
||||||
|
|
||||||
static int udf_update_inode(struct inode *inode, int do_sync)
|
static int udf_update_inode(struct inode *inode, int do_sync)
|
||||||
{
|
{
|
||||||
struct buffer_head *bh = NULL;
|
struct buffer_head *bh = NULL;
|
||||||
|
@ -1753,20 +1745,9 @@ static int udf_update_inode(struct inode *inode, int do_sync)
|
||||||
efe->objectSize = cpu_to_le64(inode->i_size);
|
efe->objectSize = cpu_to_le64(inode->i_size);
|
||||||
efe->logicalBlocksRecorded = cpu_to_le64(lb_recorded);
|
efe->logicalBlocksRecorded = cpu_to_le64(lb_recorded);
|
||||||
|
|
||||||
if (iinfo->i_crtime.tv_sec > inode->i_atime.tv_sec ||
|
udf_adjust_time(iinfo, inode->i_atime);
|
||||||
(iinfo->i_crtime.tv_sec == inode->i_atime.tv_sec &&
|
udf_adjust_time(iinfo, inode->i_mtime);
|
||||||
iinfo->i_crtime.tv_nsec > inode->i_atime.tv_nsec))
|
udf_adjust_time(iinfo, inode->i_ctime);
|
||||||
iinfo->i_crtime = inode->i_atime;
|
|
||||||
|
|
||||||
if (iinfo->i_crtime.tv_sec > inode->i_mtime.tv_sec ||
|
|
||||||
(iinfo->i_crtime.tv_sec == inode->i_mtime.tv_sec &&
|
|
||||||
iinfo->i_crtime.tv_nsec > inode->i_mtime.tv_nsec))
|
|
||||||
iinfo->i_crtime = inode->i_mtime;
|
|
||||||
|
|
||||||
if (iinfo->i_crtime.tv_sec > inode->i_ctime.tv_sec ||
|
|
||||||
(iinfo->i_crtime.tv_sec == inode->i_ctime.tv_sec &&
|
|
||||||
iinfo->i_crtime.tv_nsec > inode->i_ctime.tv_nsec))
|
|
||||||
iinfo->i_crtime = inode->i_ctime;
|
|
||||||
|
|
||||||
udf_time_to_disk_stamp(&efe->accessTime, inode->i_atime);
|
udf_time_to_disk_stamp(&efe->accessTime, inode->i_atime);
|
||||||
udf_time_to_disk_stamp(&efe->modificationTime, inode->i_mtime);
|
udf_time_to_disk_stamp(&efe->modificationTime, inode->i_mtime);
|
||||||
|
@ -2286,8 +2267,7 @@ int8_t inode_bmap(struct inode *inode, sector_t block,
|
||||||
uint32_t *elen, sector_t *offset)
|
uint32_t *elen, sector_t *offset)
|
||||||
{
|
{
|
||||||
unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
|
unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
|
||||||
loff_t lbcount = 0, bcount =
|
loff_t lbcount = 0, bcount = (loff_t) block << blocksize_bits;
|
||||||
(loff_t) block << blocksize_bits;
|
|
||||||
int8_t etype;
|
int8_t etype;
|
||||||
struct udf_inode_info *iinfo;
|
struct udf_inode_info *iinfo;
|
||||||
|
|
||||||
|
@ -2308,7 +2288,7 @@ int8_t inode_bmap(struct inode *inode, sector_t block,
|
||||||
lbcount += *elen;
|
lbcount += *elen;
|
||||||
} while (lbcount <= bcount);
|
} while (lbcount <= bcount);
|
||||||
/* update extent cache */
|
/* update extent cache */
|
||||||
udf_update_extent_cache(inode, lbcount - *elen, pos, 1);
|
udf_update_extent_cache(inode, lbcount - *elen, pos);
|
||||||
*offset = (bcount + *elen - lbcount) >> blocksize_bits;
|
*offset = (bcount + *elen - lbcount) >> blocksize_bits;
|
||||||
|
|
||||||
return etype;
|
return etype;
|
||||||
|
|
|
@ -58,7 +58,7 @@ unsigned long udf_get_last_block(struct super_block *sb)
|
||||||
*/
|
*/
|
||||||
if (ioctl_by_bdev(bdev, CDROM_LAST_WRITTEN, (unsigned long) &lblock) ||
|
if (ioctl_by_bdev(bdev, CDROM_LAST_WRITTEN, (unsigned long) &lblock) ||
|
||||||
lblock == 0)
|
lblock == 0)
|
||||||
lblock = bdev->bd_inode->i_size >> sb->s_blocksize_bits;
|
lblock = i_size_read(bdev->bd_inode) >> sb->s_blocksize_bits;
|
||||||
|
|
||||||
if (lblock)
|
if (lblock)
|
||||||
return lblock - 1;
|
return lblock - 1;
|
||||||
|
|
|
@ -141,8 +141,6 @@ struct genericFormat *udf_add_extendedattr(struct inode *inode, uint32_t size,
|
||||||
iinfo->i_lenEAttr += size;
|
iinfo->i_lenEAttr += size;
|
||||||
return (struct genericFormat *)&ea[offset];
|
return (struct genericFormat *)&ea[offset];
|
||||||
}
|
}
|
||||||
if (loc & 0x02)
|
|
||||||
;
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -931,7 +931,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
|
||||||
}
|
}
|
||||||
|
|
||||||
inode->i_data.a_ops = &udf_symlink_aops;
|
inode->i_data.a_ops = &udf_symlink_aops;
|
||||||
inode->i_op = &page_symlink_inode_operations;
|
inode->i_op = &udf_symlink_inode_operations;
|
||||||
inode_nohighmem(inode);
|
inode_nohighmem(inode);
|
||||||
|
|
||||||
if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
|
if (iinfo->i_alloc_type != ICBTAG_FLAG_AD_IN_ICB) {
|
||||||
|
|
|
@ -70,17 +70,17 @@ struct UDFIdentSuffix {
|
||||||
uint8_t OSClass;
|
uint8_t OSClass;
|
||||||
uint8_t OSIdentifier;
|
uint8_t OSIdentifier;
|
||||||
uint8_t reserved[4];
|
uint8_t reserved[4];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
struct impIdentSuffix {
|
struct impIdentSuffix {
|
||||||
uint8_t OSClass;
|
uint8_t OSClass;
|
||||||
uint8_t OSIdentifier;
|
uint8_t OSIdentifier;
|
||||||
uint8_t reserved[6];
|
uint8_t reserved[6];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
struct appIdentSuffix {
|
struct appIdentSuffix {
|
||||||
uint8_t impUse[8];
|
uint8_t impUse[8];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Logical Volume Integrity Descriptor (UDF 2.50 2.2.6) */
|
/* Logical Volume Integrity Descriptor (UDF 2.50 2.2.6) */
|
||||||
/* Implementation Use (UDF 2.50 2.2.6.4) */
|
/* Implementation Use (UDF 2.50 2.2.6.4) */
|
||||||
|
@ -92,7 +92,7 @@ struct logicalVolIntegrityDescImpUse {
|
||||||
__le16 minUDFWriteRev;
|
__le16 minUDFWriteRev;
|
||||||
__le16 maxUDFWriteRev;
|
__le16 maxUDFWriteRev;
|
||||||
uint8_t impUse[0];
|
uint8_t impUse[0];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Implementation Use Volume Descriptor (UDF 2.50 2.2.7) */
|
/* Implementation Use Volume Descriptor (UDF 2.50 2.2.7) */
|
||||||
/* Implementation Use (UDF 2.50 2.2.7.2) */
|
/* Implementation Use (UDF 2.50 2.2.7.2) */
|
||||||
|
@ -104,7 +104,7 @@ struct impUseVolDescImpUse {
|
||||||
dstring LVInfo3[36];
|
dstring LVInfo3[36];
|
||||||
struct regid impIdent;
|
struct regid impIdent;
|
||||||
uint8_t impUse[128];
|
uint8_t impUse[128];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
struct udfPartitionMap2 {
|
struct udfPartitionMap2 {
|
||||||
uint8_t partitionMapType;
|
uint8_t partitionMapType;
|
||||||
|
@ -113,7 +113,7 @@ struct udfPartitionMap2 {
|
||||||
struct regid partIdent;
|
struct regid partIdent;
|
||||||
__le16 volSeqNum;
|
__le16 volSeqNum;
|
||||||
__le16 partitionNum;
|
__le16 partitionNum;
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Virtual Partition Map (UDF 2.50 2.2.8) */
|
/* Virtual Partition Map (UDF 2.50 2.2.8) */
|
||||||
struct virtualPartitionMap {
|
struct virtualPartitionMap {
|
||||||
|
@ -124,7 +124,7 @@ struct virtualPartitionMap {
|
||||||
__le16 volSeqNum;
|
__le16 volSeqNum;
|
||||||
__le16 partitionNum;
|
__le16 partitionNum;
|
||||||
uint8_t reserved2[24];
|
uint8_t reserved2[24];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Sparable Partition Map (UDF 2.50 2.2.9) */
|
/* Sparable Partition Map (UDF 2.50 2.2.9) */
|
||||||
struct sparablePartitionMap {
|
struct sparablePartitionMap {
|
||||||
|
@ -139,7 +139,7 @@ struct sparablePartitionMap {
|
||||||
uint8_t reserved2[1];
|
uint8_t reserved2[1];
|
||||||
__le32 sizeSparingTable;
|
__le32 sizeSparingTable;
|
||||||
__le32 locSparingTable[4];
|
__le32 locSparingTable[4];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Metadata Partition Map (UDF 2.4.0 2.2.10) */
|
/* Metadata Partition Map (UDF 2.4.0 2.2.10) */
|
||||||
struct metadataPartitionMap {
|
struct metadataPartitionMap {
|
||||||
|
@ -156,14 +156,14 @@ struct metadataPartitionMap {
|
||||||
__le16 alignUnitSize;
|
__le16 alignUnitSize;
|
||||||
uint8_t flags;
|
uint8_t flags;
|
||||||
uint8_t reserved2[5];
|
uint8_t reserved2[5];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Virtual Allocation Table (UDF 1.5 2.2.10) */
|
/* Virtual Allocation Table (UDF 1.5 2.2.10) */
|
||||||
struct virtualAllocationTable15 {
|
struct virtualAllocationTable15 {
|
||||||
__le32 VirtualSector[0];
|
__le32 VirtualSector[0];
|
||||||
struct regid vatIdent;
|
struct regid vatIdent;
|
||||||
__le32 previousVATICBLoc;
|
__le32 previousVATICBLoc;
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
#define ICBTAG_FILE_TYPE_VAT15 0x00U
|
#define ICBTAG_FILE_TYPE_VAT15 0x00U
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ struct virtualAllocationTable20 {
|
||||||
__le16 reserved;
|
__le16 reserved;
|
||||||
uint8_t impUse[0];
|
uint8_t impUse[0];
|
||||||
__le32 vatEntry[0];
|
__le32 vatEntry[0];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
#define ICBTAG_FILE_TYPE_VAT20 0xF8U
|
#define ICBTAG_FILE_TYPE_VAT20 0xF8U
|
||||||
|
|
||||||
|
@ -189,7 +189,7 @@ struct virtualAllocationTable20 {
|
||||||
struct sparingEntry {
|
struct sparingEntry {
|
||||||
__le32 origLocation;
|
__le32 origLocation;
|
||||||
__le32 mappedLocation;
|
__le32 mappedLocation;
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
struct sparingTable {
|
struct sparingTable {
|
||||||
struct tag descTag;
|
struct tag descTag;
|
||||||
|
@ -199,7 +199,7 @@ struct sparingTable {
|
||||||
__le32 sequenceNum;
|
__le32 sequenceNum;
|
||||||
struct sparingEntry
|
struct sparingEntry
|
||||||
mapEntry[0];
|
mapEntry[0];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Metadata File (and Metadata Mirror File) (UDF 2.50 2.2.13.1) */
|
/* Metadata File (and Metadata Mirror File) (UDF 2.50 2.2.13.1) */
|
||||||
#define ICBTAG_FILE_TYPE_MAIN 0xFA
|
#define ICBTAG_FILE_TYPE_MAIN 0xFA
|
||||||
|
@ -210,7 +210,7 @@ struct sparingTable {
|
||||||
struct allocDescImpUse {
|
struct allocDescImpUse {
|
||||||
__le16 flags;
|
__le16 flags;
|
||||||
uint8_t impUse[4];
|
uint8_t impUse[4];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
#define AD_IU_EXT_ERASED 0x0001
|
#define AD_IU_EXT_ERASED 0x0001
|
||||||
|
|
||||||
|
@ -222,7 +222,7 @@ struct allocDescImpUse {
|
||||||
struct freeEaSpace {
|
struct freeEaSpace {
|
||||||
__le16 headerChecksum;
|
__le16 headerChecksum;
|
||||||
uint8_t freeEASpace[0];
|
uint8_t freeEASpace[0];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* DVD Copyright Management Information (UDF 2.50 3.3.4.5.1.2) */
|
/* DVD Copyright Management Information (UDF 2.50 3.3.4.5.1.2) */
|
||||||
struct DVDCopyrightImpUse {
|
struct DVDCopyrightImpUse {
|
||||||
|
@ -230,14 +230,14 @@ struct DVDCopyrightImpUse {
|
||||||
uint8_t CGMSInfo;
|
uint8_t CGMSInfo;
|
||||||
uint8_t dataType;
|
uint8_t dataType;
|
||||||
uint8_t protectionSystemInfo[4];
|
uint8_t protectionSystemInfo[4];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* Application Use Extended Attribute (UDF 2.50 3.3.4.6) */
|
/* Application Use Extended Attribute (UDF 2.50 3.3.4.6) */
|
||||||
/* FreeAppEASpace (UDF 2.50 3.3.4.6.1) */
|
/* FreeAppEASpace (UDF 2.50 3.3.4.6.1) */
|
||||||
struct freeAppEASpace {
|
struct freeAppEASpace {
|
||||||
__le16 headerChecksum;
|
__le16 headerChecksum;
|
||||||
uint8_t freeEASpace[0];
|
uint8_t freeEASpace[0];
|
||||||
} __attribute__ ((packed));
|
} __packed;
|
||||||
|
|
||||||
/* UDF Defined System Stream (UDF 2.50 3.3.7) */
|
/* UDF Defined System Stream (UDF 2.50 3.3.7) */
|
||||||
#define UDF_ID_UNIQUE_ID "*UDF Unique ID Mapping Data"
|
#define UDF_ID_UNIQUE_ID "*UDF Unique ID Mapping Data"
|
||||||
|
|
|
@ -264,9 +264,6 @@ static void __exit exit_udf_fs(void)
|
||||||
destroy_inodecache();
|
destroy_inodecache();
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(init_udf_fs)
|
|
||||||
module_exit(exit_udf_fs)
|
|
||||||
|
|
||||||
static int udf_sb_alloc_partition_maps(struct super_block *sb, u32 count)
|
static int udf_sb_alloc_partition_maps(struct super_block *sb, u32 count)
|
||||||
{
|
{
|
||||||
struct udf_sb_info *sbi = UDF_SB(sb);
|
struct udf_sb_info *sbi = UDF_SB(sb);
|
||||||
|
@ -1216,7 +1213,8 @@ static int udf_load_vat(struct super_block *sb, int p_index, int type1_index)
|
||||||
struct udf_inode_info *vati;
|
struct udf_inode_info *vati;
|
||||||
uint32_t pos;
|
uint32_t pos;
|
||||||
struct virtualAllocationTable20 *vat20;
|
struct virtualAllocationTable20 *vat20;
|
||||||
sector_t blocks = sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits;
|
sector_t blocks = i_size_read(sb->s_bdev->bd_inode) >>
|
||||||
|
sb->s_blocksize_bits;
|
||||||
|
|
||||||
udf_find_vat_block(sb, p_index, type1_index, sbi->s_last_block);
|
udf_find_vat_block(sb, p_index, type1_index, sbi->s_last_block);
|
||||||
if (!sbi->s_vat_inode &&
|
if (!sbi->s_vat_inode &&
|
||||||
|
@ -1806,7 +1804,7 @@ static int udf_check_anchor_block(struct super_block *sb, sector_t block,
|
||||||
|
|
||||||
if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV) &&
|
if (UDF_QUERY_FLAG(sb, UDF_FLAG_VARCONV) &&
|
||||||
udf_fixed_to_variable(block) >=
|
udf_fixed_to_variable(block) >=
|
||||||
sb->s_bdev->bd_inode->i_size >> sb->s_blocksize_bits)
|
i_size_read(sb->s_bdev->bd_inode) >> sb->s_blocksize_bits)
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
|
|
||||||
bh = udf_read_tagged(sb, block, block, &ident);
|
bh = udf_read_tagged(sb, block, block, &ident);
|
||||||
|
@ -1868,7 +1866,7 @@ static int udf_scan_anchors(struct super_block *sb, sector_t *lastblock,
|
||||||
last[last_count++] = *lastblock - 152;
|
last[last_count++] = *lastblock - 152;
|
||||||
|
|
||||||
for (i = 0; i < last_count; i++) {
|
for (i = 0; i < last_count; i++) {
|
||||||
if (last[i] >= sb->s_bdev->bd_inode->i_size >>
|
if (last[i] >= i_size_read(sb->s_bdev->bd_inode) >>
|
||||||
sb->s_blocksize_bits)
|
sb->s_blocksize_bits)
|
||||||
continue;
|
continue;
|
||||||
ret = udf_check_anchor_block(sb, last[i], fileset);
|
ret = udf_check_anchor_block(sb, last[i], fileset);
|
||||||
|
@ -1957,7 +1955,7 @@ static int udf_load_vrs(struct super_block *sb, struct udf_options *uopt,
|
||||||
if (!nsr_off) {
|
if (!nsr_off) {
|
||||||
if (!silent)
|
if (!silent)
|
||||||
udf_warn(sb, "No VRS found\n");
|
udf_warn(sb, "No VRS found\n");
|
||||||
return 0;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (nsr_off == -1)
|
if (nsr_off == -1)
|
||||||
udf_debug("Failed to read sector at offset %d. "
|
udf_debug("Failed to read sector at offset %d. "
|
||||||
|
@ -1986,6 +1984,7 @@ static void udf_open_lvid(struct super_block *sb)
|
||||||
struct buffer_head *bh = sbi->s_lvid_bh;
|
struct buffer_head *bh = sbi->s_lvid_bh;
|
||||||
struct logicalVolIntegrityDesc *lvid;
|
struct logicalVolIntegrityDesc *lvid;
|
||||||
struct logicalVolIntegrityDescImpUse *lvidiu;
|
struct logicalVolIntegrityDescImpUse *lvidiu;
|
||||||
|
struct timespec ts;
|
||||||
|
|
||||||
if (!bh)
|
if (!bh)
|
||||||
return;
|
return;
|
||||||
|
@ -1997,8 +1996,8 @@ static void udf_open_lvid(struct super_block *sb)
|
||||||
mutex_lock(&sbi->s_alloc_mutex);
|
mutex_lock(&sbi->s_alloc_mutex);
|
||||||
lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
|
lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
|
||||||
lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
|
lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
|
||||||
udf_time_to_disk_stamp(&lvid->recordingDateAndTime,
|
ktime_get_real_ts(&ts);
|
||||||
CURRENT_TIME);
|
udf_time_to_disk_stamp(&lvid->recordingDateAndTime, ts);
|
||||||
lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN);
|
lvid->integrityType = cpu_to_le32(LVID_INTEGRITY_TYPE_OPEN);
|
||||||
|
|
||||||
lvid->descTag.descCRC = cpu_to_le16(
|
lvid->descTag.descCRC = cpu_to_le16(
|
||||||
|
@ -2019,6 +2018,7 @@ static void udf_close_lvid(struct super_block *sb)
|
||||||
struct buffer_head *bh = sbi->s_lvid_bh;
|
struct buffer_head *bh = sbi->s_lvid_bh;
|
||||||
struct logicalVolIntegrityDesc *lvid;
|
struct logicalVolIntegrityDesc *lvid;
|
||||||
struct logicalVolIntegrityDescImpUse *lvidiu;
|
struct logicalVolIntegrityDescImpUse *lvidiu;
|
||||||
|
struct timespec ts;
|
||||||
|
|
||||||
if (!bh)
|
if (!bh)
|
||||||
return;
|
return;
|
||||||
|
@ -2030,7 +2030,8 @@ static void udf_close_lvid(struct super_block *sb)
|
||||||
mutex_lock(&sbi->s_alloc_mutex);
|
mutex_lock(&sbi->s_alloc_mutex);
|
||||||
lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
|
lvidiu->impIdent.identSuffix[0] = UDF_OS_CLASS_UNIX;
|
||||||
lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
|
lvidiu->impIdent.identSuffix[1] = UDF_OS_ID_LINUX;
|
||||||
udf_time_to_disk_stamp(&lvid->recordingDateAndTime, CURRENT_TIME);
|
ktime_get_real_ts(&ts);
|
||||||
|
udf_time_to_disk_stamp(&lvid->recordingDateAndTime, ts);
|
||||||
if (UDF_MAX_WRITE_VERSION > le16_to_cpu(lvidiu->maxUDFWriteRev))
|
if (UDF_MAX_WRITE_VERSION > le16_to_cpu(lvidiu->maxUDFWriteRev))
|
||||||
lvidiu->maxUDFWriteRev = cpu_to_le16(UDF_MAX_WRITE_VERSION);
|
lvidiu->maxUDFWriteRev = cpu_to_le16(UDF_MAX_WRITE_VERSION);
|
||||||
if (sbi->s_udfrev > le16_to_cpu(lvidiu->minUDFReadRev))
|
if (sbi->s_udfrev > le16_to_cpu(lvidiu->minUDFReadRev))
|
||||||
|
@ -2158,15 +2159,25 @@ static int udf_fill_super(struct super_block *sb, void *options, int silent)
|
||||||
ret = udf_load_vrs(sb, &uopt, silent, &fileset);
|
ret = udf_load_vrs(sb, &uopt, silent, &fileset);
|
||||||
} else {
|
} else {
|
||||||
uopt.blocksize = bdev_logical_block_size(sb->s_bdev);
|
uopt.blocksize = bdev_logical_block_size(sb->s_bdev);
|
||||||
ret = udf_load_vrs(sb, &uopt, silent, &fileset);
|
while (uopt.blocksize <= 4096) {
|
||||||
if (ret == -EAGAIN && uopt.blocksize != UDF_DEFAULT_BLOCKSIZE) {
|
|
||||||
if (!silent)
|
|
||||||
pr_notice("Rescanning with blocksize %d\n",
|
|
||||||
UDF_DEFAULT_BLOCKSIZE);
|
|
||||||
brelse(sbi->s_lvid_bh);
|
|
||||||
sbi->s_lvid_bh = NULL;
|
|
||||||
uopt.blocksize = UDF_DEFAULT_BLOCKSIZE;
|
|
||||||
ret = udf_load_vrs(sb, &uopt, silent, &fileset);
|
ret = udf_load_vrs(sb, &uopt, silent, &fileset);
|
||||||
|
if (ret < 0) {
|
||||||
|
if (!silent && ret != -EACCES) {
|
||||||
|
pr_notice("Scanning with blocksize %d failed\n",
|
||||||
|
uopt.blocksize);
|
||||||
|
}
|
||||||
|
brelse(sbi->s_lvid_bh);
|
||||||
|
sbi->s_lvid_bh = NULL;
|
||||||
|
/*
|
||||||
|
* EACCES is special - we want to propagate to
|
||||||
|
* upper layers that we cannot handle RW mount.
|
||||||
|
*/
|
||||||
|
if (ret == -EACCES)
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
break;
|
||||||
|
|
||||||
|
uopt.blocksize <<= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -2497,3 +2508,9 @@ static unsigned int udf_count_free(struct super_block *sb)
|
||||||
|
|
||||||
return accum;
|
return accum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MODULE_AUTHOR("Ben Fennema");
|
||||||
|
MODULE_DESCRIPTION("Universal Disk Format Filesystem");
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
module_init(init_udf_fs)
|
||||||
|
module_exit(exit_udf_fs)
|
||||||
|
|
|
@ -152,9 +152,39 @@ static int udf_symlink_filler(struct file *file, struct page *page)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int udf_symlink_getattr(struct vfsmount *mnt, struct dentry *dentry,
|
||||||
|
struct kstat *stat)
|
||||||
|
{
|
||||||
|
struct inode *inode = d_backing_inode(dentry);
|
||||||
|
struct page *page;
|
||||||
|
|
||||||
|
generic_fillattr(inode, stat);
|
||||||
|
page = read_mapping_page(inode->i_mapping, 0, NULL);
|
||||||
|
if (IS_ERR(page))
|
||||||
|
return PTR_ERR(page);
|
||||||
|
/*
|
||||||
|
* UDF uses non-trivial encoding of symlinks so i_size does not match
|
||||||
|
* number of characters reported by readlink(2) which apparently some
|
||||||
|
* applications expect. Also POSIX says that "The value returned in the
|
||||||
|
* st_size field shall be the length of the contents of the symbolic
|
||||||
|
* link, and shall not count a trailing null if one is present." So
|
||||||
|
* let's report the length of string returned by readlink(2) for
|
||||||
|
* st_size.
|
||||||
|
*/
|
||||||
|
stat->size = strlen(page_address(page));
|
||||||
|
put_page(page);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* symlinks can't do much...
|
* symlinks can't do much...
|
||||||
*/
|
*/
|
||||||
const struct address_space_operations udf_symlink_aops = {
|
const struct address_space_operations udf_symlink_aops = {
|
||||||
.readpage = udf_symlink_filler,
|
.readpage = udf_symlink_filler,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const struct inode_operations udf_symlink_inode_operations = {
|
||||||
|
.get_link = page_get_link,
|
||||||
|
.getattr = udf_symlink_getattr,
|
||||||
|
};
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include "udfend.h"
|
#include "udfend.h"
|
||||||
#include "udf_i.h"
|
#include "udf_i.h"
|
||||||
|
|
||||||
#define UDF_PREALLOCATE
|
|
||||||
#define UDF_DEFAULT_PREALLOC_BLOCKS 8
|
#define UDF_DEFAULT_PREALLOC_BLOCKS 8
|
||||||
|
|
||||||
extern __printf(3, 4) void _udf_err(struct super_block *sb,
|
extern __printf(3, 4) void _udf_err(struct super_block *sb,
|
||||||
|
@ -85,6 +84,7 @@ extern const struct inode_operations udf_dir_inode_operations;
|
||||||
extern const struct file_operations udf_dir_operations;
|
extern const struct file_operations udf_dir_operations;
|
||||||
extern const struct inode_operations udf_file_inode_operations;
|
extern const struct inode_operations udf_file_inode_operations;
|
||||||
extern const struct file_operations udf_file_operations;
|
extern const struct file_operations udf_file_operations;
|
||||||
|
extern const struct inode_operations udf_symlink_inode_operations;
|
||||||
extern const struct address_space_operations udf_aops;
|
extern const struct address_space_operations udf_aops;
|
||||||
extern const struct address_space_operations udf_adinicb_aops;
|
extern const struct address_space_operations udf_adinicb_aops;
|
||||||
extern const struct address_space_operations udf_symlink_aops;
|
extern const struct address_space_operations udf_symlink_aops;
|
||||||
|
|
Loading…
Reference in a new issue