Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
cloud-kernel
提交
076fb01e
cloud-kernel
项目概览
openanolis
/
cloud-kernel
大约 1 年 前同步成功
通知
158
Star
36
Fork
7
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
10
列表
看板
标记
里程碑
合并请求
2
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
cloud-kernel
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
10
Issue
10
列表
看板
标记
里程碑
合并请求
2
合并请求
2
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
076fb01e
编写于
7月 19, 2005
作者:
S
Steve French
浏览文件
操作
浏览文件
下载
差异文件
Merge with
rsync://rsync.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
上级
4c48b0d3
f60f7008
变更
48
展开全部
隐藏空白更改
内联
并排
Showing
48 changed file
with
2745 addition
and
1265 deletion
+2745
-1265
Documentation/dontdiff
Documentation/dontdiff
+2
-0
Documentation/feature-removal-schedule.txt
Documentation/feature-removal-schedule.txt
+2
-2
Documentation/filesystems/ntfs.txt
Documentation/filesystems/ntfs.txt
+27
-2
arch/arm/configs/shark_defconfig
arch/arm/configs/shark_defconfig
+52
-33
arch/arm/kernel/traps.c
arch/arm/kernel/traps.c
+8
-4
arch/arm/lib/bitops.h
arch/arm/lib/bitops.h
+31
-0
arch/arm/lib/io-shark.c
arch/arm/lib/io-shark.c
+0
-70
arch/arm/mach-shark/core.c
arch/arm/mach-shark/core.c
+2
-2
arch/ia64/kernel/topology.c
arch/ia64/kernel/topology.c
+2
-0
arch/x86_64/ia32/syscall32.c
arch/x86_64/ia32/syscall32.c
+6
-1
drivers/mtd/nand/nand_base.c
drivers/mtd/nand/nand_base.c
+11
-11
drivers/mtd/nand/nand_bbt.c
drivers/mtd/nand/nand_bbt.c
+9
-11
drivers/serial/crisv10.c
drivers/serial/crisv10.c
+0
-2
drivers/serial/icom.c
drivers/serial/icom.c
+0
-1
drivers/serial/jsm/jsm.h
drivers/serial/jsm/jsm.h
+0
-1
fs/jffs2/erase.c
fs/jffs2/erase.c
+92
-82
fs/ntfs/ChangeLog
fs/ntfs/ChangeLog
+161
-18
fs/ntfs/Makefile
fs/ntfs/Makefile
+2
-2
fs/ntfs/aops.c
fs/ntfs/aops.c
+110
-56
fs/ntfs/attrib.c
fs/ntfs/attrib.c
+544
-86
fs/ntfs/attrib.h
fs/ntfs/attrib.h
+13
-3
fs/ntfs/compress.c
fs/ntfs/compress.c
+28
-18
fs/ntfs/debug.c
fs/ntfs/debug.c
+9
-6
fs/ntfs/dir.c
fs/ntfs/dir.c
+15
-17
fs/ntfs/file.c
fs/ntfs/file.c
+1
-1
fs/ntfs/index.c
fs/ntfs/index.c
+3
-13
fs/ntfs/inode.c
fs/ntfs/inode.c
+262
-268
fs/ntfs/inode.h
fs/ntfs/inode.h
+5
-2
fs/ntfs/layout.h
fs/ntfs/layout.h
+47
-36
fs/ntfs/lcnalloc.c
fs/ntfs/lcnalloc.c
+29
-43
fs/ntfs/logfile.c
fs/ntfs/logfile.c
+6
-5
fs/ntfs/mft.c
fs/ntfs/mft.c
+155
-72
fs/ntfs/namei.c
fs/ntfs/namei.c
+30
-4
fs/ntfs/ntfs.h
fs/ntfs/ntfs.h
+7
-1
fs/ntfs/runlist.c
fs/ntfs/runlist.c
+198
-80
fs/ntfs/runlist.h
fs/ntfs/runlist.h
+13
-3
fs/ntfs/super.c
fs/ntfs/super.c
+542
-150
fs/ntfs/sysctl.c
fs/ntfs/sysctl.c
+2
-2
fs/ntfs/time.h
fs/ntfs/time.h
+2
-2
fs/ntfs/types.h
fs/ntfs/types.h
+9
-1
fs/ntfs/unistr.c
fs/ntfs/unistr.c
+1
-1
fs/ntfs/usnjrnl.c
fs/ntfs/usnjrnl.c
+84
-0
fs/ntfs/usnjrnl.h
fs/ntfs/usnjrnl.h
+205
-0
fs/ntfs/volume.h
fs/ntfs/volume.h
+10
-2
include/asm-arm/arch-shark/io.h
include/asm-arm/arch-shark/io.h
+1
-146
include/linux/serial.h
include/linux/serial.h
+4
-2
include/linux/serialP.h
include/linux/serialP.h
+0
-1
include/linux/serial_core.h
include/linux/serial_core.h
+3
-2
未找到文件。
Documentation/dontdiff
浏览文件 @
076fb01e
...
...
@@ -41,6 +41,7 @@ COPYING
CREDITS
CVS
ChangeSet
Image
Kerntypes
MODS.txt
Module.symvers
...
...
@@ -103,6 +104,7 @@ logo_*.c
logo_*_clut224.c
logo_*_mono.c
lxdialog
mach-types.h
make_times_h
map
maui_boot.h
...
...
Documentation/feature-removal-schedule.txt
浏览文件 @
076fb01e
...
...
@@ -103,11 +103,11 @@ Who: Jody McIntyre <scjody@steamballoon.com>
---------------------------
What: register_serial/unregister_serial
When:
Dec
ember 2005
When:
Sept
ember 2005
Why: This interface does not allow serial ports to be registered against
a struct device, and as such does not allow correct power management
of such ports. 8250-based ports should use serial8250_register_port
and serial8250_unregister_port instead.
and serial8250_unregister_port
, or platform devices
instead.
Who: Russell King <rmk@arm.linux.org.uk>
---------------------------
...
...
Documentation/filesystems/ntfs.txt
浏览文件 @
076fb01e
...
...
@@ -21,7 +21,7 @@ Overview
========
Linux-NTFS comes with a number of user-space programs known as ntfsprogs.
These include mkntfs, a full-featured ntfs file
system format utility,
These include mkntfs, a full-featured ntfs filesystem format utility,
ntfsundelete used for recovering files that were unintentionally deleted
from an NTFS volume and ntfsresize which is used to resize an NTFS partition.
See the web site for more information.
...
...
@@ -149,7 +149,14 @@ case_sensitive=<BOOL> If case_sensitive is specified, treat all file names as
name, if it exists. If case_sensitive, you will need
to provide the correct case of the short file name.
errors=opt What to do when critical file system errors are found.
disable_sparse=<BOOL> If disable_sparse is specified, creation of sparse
regions, i.e. holes, inside files is disabled for the
volume (for the duration of this mount only). By
default, creation of sparse regions is enabled, which
is consistent with the behaviour of traditional Unix
filesystems.
errors=opt What to do when critical filesystem errors are found.
Following values can be used for "opt":
continue: DEFAULT, try to clean-up as much as
possible, e.g. marking a corrupt inode as
...
...
@@ -432,6 +439,24 @@ ChangeLog
Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog.
2.1.23:
- Stamp the user space journal, aka transaction log, aka $UsnJrnl, if
it is present and active thus telling Windows and applications using
the transaction log that changes can have happened on the volume
which are not recorded in $UsnJrnl.
- Detect the case when Windows has been hibernated (suspended to disk)
and if this is the case do not allow (re)mounting read-write to
prevent data corruption when you boot back into the suspended
Windows session.
- Implement extension of resident files using the normal file write
code paths, i.e. most very small files can be extended to be a little
bit bigger but not by much.
- Add new mount option "disable_sparse". (See list of mount options
above for details.)
- Improve handling of ntfs volumes with errors and strange boot sectors
in particular.
- Fix various bugs including a nasty deadlock that appeared in recent
kernels (around 2.6.11-2.6.12 timeframe).
2.1.22:
- Improve handling of ntfs volumes with errors.
- Fix various bugs and race conditions.
...
...
arch/arm/configs/shark_defconfig
浏览文件 @
076fb01e
#
# Automatically generated make config: don't edit
# Linux kernel version: 2.6.12-
rc1-bk2
# S
un Mar 27 23:59:14
2005
# Linux kernel version: 2.6.12-
git3
# S
at Jul 16 15:21:47
2005
#
CONFIG_ARM=y
CONFIG_MMU=y
CONFIG_UID16=y
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_GENERIC_IOMAP=y
#
# Code maturity level options
#
CONFIG_EXPERIMENTAL=y
# CONFIG_CLEAN_COMPILE is not set
CONFIG_BROKEN=y
CONFIG_CLEAN_COMPILE=y
CONFIG_BROKEN_ON_SMP=y
CONFIG_INIT_ENV_ARG_LIMIT=32
#
# General setup
...
...
@@ -33,7 +32,10 @@ CONFIG_KOBJECT_UEVENT=y
# CONFIG_IKCONFIG is not set
# CONFIG_EMBEDDED is not set
CONFIG_KALLSYMS=y
# CONFIG_KALLSYMS_ALL is not set
# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_PRINTK=y
CONFIG_BUG=y
CONFIG_BASE_FULL=y
CONFIG_FUTEX=y
CONFIG_EPOLL=y
...
...
@@ -81,6 +83,7 @@ CONFIG_ARCH_SHARK=y
# CONFIG_ARCH_VERSATILE is not set
# CONFIG_ARCH_IMX is not set
# CONFIG_ARCH_H720X is not set
# CONFIG_ARCH_AAEC2000 is not set
#
# Processor Type
...
...
@@ -103,10 +106,12 @@ CONFIG_CPU_TLB_V4WB=y
#
CONFIG_ISA=y
CONFIG_ISA_DMA=y
CONFIG_ISA_DMA_API=y
CONFIG_PCI=y
CONFIG_PCI_HOST_VIA82C505=y
CONFIG_PCI_LEGACY_PROC=y
# CONFIG_PCI_NAMES is not set
# CONFIG_PCI_DEBUG is not set
#
# PCCARD (PCMCIA/CardBus) support
...
...
@@ -116,7 +121,9 @@ CONFIG_PCI_LEGACY_PROC=y
#
# Kernel Features
#
# CONFIG_SMP is not set
# CONFIG_PREEMPT is not set
# CONFIG_DISCONTIGMEM is not set
CONFIG_LEDS=y
CONFIG_LEDS_TIMER=y
# CONFIG_LEDS_CPU is not set
...
...
@@ -163,6 +170,7 @@ CONFIG_BINFMT_ELF=y
# CONFIG_STANDALONE is not set
CONFIG_PREVENT_FIRMWARE_BUILD=y
# CONFIG_FW_LOADER is not set
# CONFIG_DEBUG_DRIVER is not set
#
# Memory Technology Devices (MTD)
...
...
@@ -172,8 +180,8 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y
#
# Parallel port support
#
CONFIG_PARPORT=
y
CONFIG_PARPORT_PC=
y
CONFIG_PARPORT=
m
CONFIG_PARPORT_PC=
m
# CONFIG_PARPORT_SERIAL is not set
# CONFIG_PARPORT_PC_FIFO is not set
# CONFIG_PARPORT_PC_SUPERIO is not set
...
...
@@ -189,7 +197,6 @@ CONFIG_PARPORT_PC=y
#
# Block devices
#
# CONFIG_BLK_DEV_FD is not set
# CONFIG_BLK_DEV_XD is not set
# CONFIG_PARIDE is not set
# CONFIG_BLK_CPQ_DA is not set
...
...
@@ -229,7 +236,7 @@ CONFIG_BLK_DEV_IDE=y
# CONFIG_BLK_DEV_IDE_SATA is not set
CONFIG_BLK_DEV_IDEDISK=y
# CONFIG_IDEDISK_MULTI_MODE is not set
CONFIG_BLK_DEV_IDECD=
y
CONFIG_BLK_DEV_IDECD=
m
# CONFIG_BLK_DEV_IDETAPE is not set
CONFIG_BLK_DEV_IDEFLOPPY=y
# CONFIG_BLK_DEV_IDESCSI is not set
...
...
@@ -261,6 +268,7 @@ CONFIG_CHR_DEV_ST=m
CONFIG_BLK_DEV_SR=m
# CONFIG_BLK_DEV_SR_VENDOR is not set
CONFIG_CHR_DEV_SG=m
# CONFIG_CHR_DEV_SCH is not set
#
# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
...
...
@@ -290,17 +298,14 @@ CONFIG_CHR_DEV_SG=m
# CONFIG_SCSI_AIC7XXX_OLD is not set
# CONFIG_SCSI_AIC79XX is not set
# CONFIG_SCSI_DPT_I2O is not set
# CONFIG_SCSI_ADVANSYS is not set
# CONFIG_SCSI_IN2000 is not set
# CONFIG_MEGARAID_NEWGEN is not set
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_SCSI_SATA is not set
# CONFIG_SCSI_BUSLOGIC is not set
# CONFIG_SCSI_CPQFCTS is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_DTC3280 is not set
# CONFIG_SCSI_EATA is not set
# CONFIG_SCSI_EATA_PIO is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_GDTH is not set
# CONFIG_SCSI_GENERIC_NCR5380 is not set
...
...
@@ -314,11 +319,8 @@ CONFIG_CHR_DEV_SG=m
# CONFIG_SCSI_SYM53C8XX_2 is not set
# CONFIG_SCSI_IPR is not set
# CONFIG_SCSI_PAS16 is not set
# CONFIG_SCSI_PCI2000 is not set
# CONFIG_SCSI_PCI2220I is not set
# CONFIG_SCSI_PSI240I is not set
# CONFIG_SCSI_QLOGIC_FAS is not set
# CONFIG_SCSI_QLOGIC_ISP is not set
# CONFIG_SCSI_QLOGIC_FC is not set
# CONFIG_SCSI_QLOGIC_1280 is not set
CONFIG_SCSI_QLA2XXX=m
...
...
@@ -327,6 +329,7 @@ CONFIG_SCSI_QLA2XXX=m
# CONFIG_SCSI_QLA2300 is not set
# CONFIG_SCSI_QLA2322 is not set
# CONFIG_SCSI_QLA6312 is not set
# CONFIG_SCSI_LPFC is not set
# CONFIG_SCSI_SYM53C416 is not set
# CONFIG_SCSI_DC395x is not set
# CONFIG_SCSI_DC390T is not set
...
...
@@ -344,6 +347,8 @@ CONFIG_SCSI_QLA2XXX=m
# Fusion MPT device support
#
# CONFIG_FUSION is not set
# CONFIG_FUSION_SPI is not set
# CONFIG_FUSION_FC is not set
#
# IEEE 1394 (FireWire) support
...
...
@@ -365,7 +370,6 @@ CONFIG_NET=y
#
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
# CONFIG_NETLINK_DEV is not set
CONFIG_UNIX=y
# CONFIG_NET_KEY is not set
CONFIG_INET=y
...
...
@@ -380,7 +384,7 @@ CONFIG_INET=y
# CONFIG_INET_ESP is not set
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_TUNNEL is not set
# CONFIG_IP_TCPDIAG is not set
CONFIG_IP_TCPDIAG=y
# CONFIG_IP_TCPDIAG_IPV6 is not set
# CONFIG_IPV6 is not set
# CONFIG_NETFILTER is not set
...
...
@@ -439,6 +443,7 @@ CONFIG_NET_ETHERNET=y
# CONFIG_LANCE is not set
# CONFIG_NET_VENDOR_SMC is not set
# CONFIG_SMC91X is not set
# CONFIG_DM9000 is not set
# CONFIG_NET_VENDOR_RACAL is not set
#
...
...
@@ -483,9 +488,11 @@ CONFIG_CS89x0=y
# CONFIG_HAMACHI is not set
# CONFIG_YELLOWFIN is not set
# CONFIG_R8169 is not set
# CONFIG_SKGE is not set
# CONFIG_SK98LIN is not set
# CONFIG_VIA_VELOCITY is not set
# CONFIG_TIGON3 is not set
# CONFIG_BNX2 is not set
#
# Ethernet (10000 Mbit)
...
...
@@ -569,7 +576,6 @@ CONFIG_SERIO_I8042=y
CONFIG_SERIO_LIBPS2=y
# CONFIG_SERIO_RAW is not set
# CONFIG_GAMEPORT is not set
CONFIG_SOUND_GAMEPORT=y
#
# Character devices
...
...
@@ -592,6 +598,7 @@ CONFIG_SERIAL_8250_NR_UARTS=4
#
CONFIG_SERIAL_CORE=y
CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
...
...
@@ -653,6 +660,7 @@ CONFIG_FB_CFB_FILLRECT=y
CONFIG_FB_CFB_COPYAREA=y
CONFIG_FB_CFB_IMAGEBLIT=y
CONFIG_FB_SOFT_CURSOR=y
# CONFIG_FB_MACMODES is not set
# CONFIG_FB_MODE_HELPERS is not set
# CONFIG_FB_TILEBLITTING is not set
# CONFIG_FB_CIRRUS is not set
...
...
@@ -674,7 +682,7 @@ CONFIG_FB_CYBER2000=y
# CONFIG_FB_3DFX is not set
# CONFIG_FB_VOODOO1 is not set
# CONFIG_FB_TRIDENT is not set
# CONFIG_FB_
PM3
is not set
# CONFIG_FB_
S1D13XXX
is not set
# CONFIG_FB_VIRTUAL is not set
#
...
...
@@ -808,7 +816,7 @@ CONFIG_DNOTIFY=y
#
# CD-ROM/DVD Filesystems
#
CONFIG_ISO9660_FS=
y
CONFIG_ISO9660_FS=
m
CONFIG_JOLIET=y
# CONFIG_ZISOFS is not set
# CONFIG_UDF_FS is not set
...
...
@@ -816,9 +824,9 @@ CONFIG_JOLIET=y
#
# DOS/FAT/NT Filesystems
#
CONFIG_FAT_FS=
y
CONFIG_MSDOS_FS=
y
CONFIG_VFAT_FS=
y
CONFIG_FAT_FS=
m
CONFIG_MSDOS_FS=
m
CONFIG_VFAT_FS=
m
CONFIG_FAT_DEFAULT_CODEPAGE=437
CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
# CONFIG_NTFS_FS is not set
...
...
@@ -833,7 +841,6 @@ CONFIG_DEVFS_MOUNT=y
# CONFIG_DEVFS_DEBUG is not set
# CONFIG_DEVPTS_FS_XATTR is not set
# CONFIG_TMPFS is not set
# CONFIG_HUGETLBFS is not set
# CONFIG_HUGETLB_PAGE is not set
CONFIG_RAMFS=y
...
...
@@ -857,13 +864,14 @@ CONFIG_RAMFS=y
#
# Network File Systems
#
CONFIG_NFS_FS=
y
# CONFIG_NFS_V3 is not set
CONFIG_NFS_FS=
m
CONFIG_NFS_V3=y
# CONFIG_NFS_V4 is not set
# CONFIG_NFS_DIRECTIO is not set
# CONFIG_NFSD is not set
CONFIG_LOCKD=y
CONFIG_SUNRPC=y
CONFIG_LOCKD=m
CONFIG_LOCKD_V4=y
CONFIG_SUNRPC=m
# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
...
...
@@ -895,12 +903,12 @@ CONFIG_MSDOS_PARTITION=y
#
# Native Language Support
#
CONFIG_NLS=
y
CONFIG_NLS=
m
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=
y
CONFIG_NLS_CODEPAGE_437=
m
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
CONFIG_NLS_CODEPAGE_850=
y
CONFIG_NLS_CODEPAGE_850=
m
# CONFIG_NLS_CODEPAGE_852 is not set
# CONFIG_NLS_CODEPAGE_855 is not set
# CONFIG_NLS_CODEPAGE_857 is not set
...
...
@@ -921,7 +929,7 @@ CONFIG_NLS_CODEPAGE_850=y
# CONFIG_NLS_CODEPAGE_1250 is not set
# CONFIG_NLS_CODEPAGE_1251 is not set
# CONFIG_NLS_ASCII is not set
CONFIG_NLS_ISO8859_1=
y
CONFIG_NLS_ISO8859_1=
m
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
# CONFIG_NLS_ISO8859_4 is not set
...
...
@@ -945,11 +953,22 @@ CONFIG_NLS_ISO8859_1=y
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
# CONFIG_DEBUG_KERNEL is not set
CONFIG_DEBUG_KERNEL=y
# CONFIG_MAGIC_SYSRQ is not set
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_SCHEDSTATS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_SPINLOCK is not set
# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
# CONFIG_DEBUG_KOBJECT is not set
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_FS is not set
CONFIG_FRAME_POINTER=y
CONFIG_DEBUG_USER=y
# CONFIG_DEBUG_WAITQ is not set
# CONFIG_DEBUG_ERRORS is not set
# CONFIG_DEBUG_LL is not set
#
# Security options
...
...
arch/arm/kernel/traps.c
浏览文件 @
076fb01e
...
...
@@ -248,16 +248,20 @@ static DEFINE_SPINLOCK(undef_lock);
void
register_undef_hook
(
struct
undef_hook
*
hook
)
{
spin_lock_irq
(
&
undef_lock
);
unsigned
long
flags
;
spin_lock_irqsave
(
&
undef_lock
,
flags
);
list_add
(
&
hook
->
node
,
&
undef_hook
);
spin_unlock_irq
(
&
undef_lock
);
spin_unlock_irq
restore
(
&
undef_lock
,
flags
);
}
void
unregister_undef_hook
(
struct
undef_hook
*
hook
)
{
spin_lock_irq
(
&
undef_lock
);
unsigned
long
flags
;
spin_lock_irqsave
(
&
undef_lock
,
flags
);
list_del
(
&
hook
->
node
);
spin_unlock_irq
(
&
undef_lock
);
spin_unlock_irq
restore
(
&
undef_lock
,
flags
);
}
asmlinkage
void
do_undefinstr
(
struct
pt_regs
*
regs
)
...
...
arch/arm/lib/bitops.h
浏览文件 @
076fb01e
#if __LINUX_ARM_ARCH__ >= 6
.
macro
bitop
,
instr
mov
r2
,
#
1
and
r3
,
r0
,
#
7
@
Get
bit
offset
add
r1
,
r1
,
r0
,
lsr
#
3
@
Get
byte
offset
mov
r3
,
r2
,
lsl
r3
1
:
ldrexb
r2
,
[
r1
]
\
instr
r2
,
r2
,
r3
strexb
r0
,
r2
,
[
r1
]
cmpne
r0
,
#
0
bne
1
b
mov
pc
,
lr
.
endm
.
macro
testop
,
instr
,
store
and
r3
,
r0
,
#
7
@
Get
bit
offset
mov
r2
,
#
1
add
r1
,
r1
,
r0
,
lsr
#
3
@
Get
byte
offset
mov
r3
,
r2
,
lsl
r3
@
create
mask
1
:
ldrexb
r2
,
[
r1
]
ands
r0
,
r2
,
r3
@
save
old
value
of
bit
\
instr
ip
,
r2
,
r3
@
toggle
bit
strexb
r2
,
ip
,
[
r1
]
cmp
r2
,
#
0
bne
1
b
cmp
r0
,
#
0
movne
r0
,
#
1
2
:
mov
pc
,
lr
.
endm
#else
.
macro
bitop
,
instr
and
r2
,
r0
,
#
7
mov
r3
,
#
1
...
...
@@ -31,3 +61,4 @@
moveq
r0
,
#
0
mov
pc
,
lr
.
endm
#endif
arch/arm/lib/io-shark.c
浏览文件 @
076fb01e
...
...
@@ -11,73 +11,3 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <asm/io.h>
void
print_warning
(
void
)
{
printk
(
KERN_WARNING
"ins?/outs? not implemented on this architecture
\n
"
);
}
void
insl
(
unsigned
int
port
,
void
*
to
,
int
len
)
{
print_warning
();
}
void
insb
(
unsigned
int
port
,
void
*
to
,
int
len
)
{
print_warning
();
}
void
outsl
(
unsigned
int
port
,
const
void
*
from
,
int
len
)
{
print_warning
();
}
void
outsb
(
unsigned
int
port
,
const
void
*
from
,
int
len
)
{
print_warning
();
}
/* these should be in assembler again */
/*
* Purpose: read a block of data from a hardware register to memory.
* Proto : insw(int from_port, void *to, int len_in_words);
* Proto : inswb(int from_port, void *to, int len_in_bytes);
* Notes : increment to
*/
void
insw
(
unsigned
int
port
,
void
*
to
,
int
len
)
{
int
i
;
for
(
i
=
0
;
i
<
len
;
i
++
)
((
unsigned
short
*
)
to
)[
i
]
=
inw
(
port
);
}
void
inswb
(
unsigned
int
port
,
void
*
to
,
int
len
)
{
insw
(
port
,
to
,
len
>>
2
);
}
/*
* Purpose: write a block of data from memory to a hardware register.
* Proto : outsw(int to_reg, void *from, int len_in_words);
* Proto : outswb(int to_reg, void *from, int len_in_bytes);
* Notes : increments from
*/
void
outsw
(
unsigned
int
port
,
const
void
*
from
,
int
len
)
{
int
i
;
for
(
i
=
0
;
i
<
len
;
i
++
)
outw
(((
unsigned
short
*
)
from
)[
i
],
port
);
}
void
outswb
(
unsigned
int
port
,
const
void
*
from
,
int
len
)
{
outsw
(
port
,
from
,
len
>>
2
);
}
arch/arm/mach-shark/core.c
浏览文件 @
076fb01e
...
...
@@ -24,7 +24,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
.
iobase
=
0x3f8
,
.
irq
=
4
,
.
uartclk
=
1843200
,
.
regshift
=
2
,
.
regshift
=
0
,
.
iotype
=
UPIO_PORT
,
.
flags
=
UPF_BOOT_AUTOCONF
|
UPF_SKIP_TEST
,
},
...
...
@@ -32,7 +32,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
.
iobase
=
0x2f8
,
.
irq
=
3
,
.
uartclk
=
1843200
,
.
regshift
=
2
,
.
regshift
=
0
,
.
iotype
=
UPIO_PORT
,
.
flags
=
UPF_BOOT_AUTOCONF
|
UPF_SKIP_TEST
,
},
...
...
arch/ia64/kernel/topology.c
浏览文件 @
076fb01e
...
...
@@ -36,12 +36,14 @@ int arch_register_cpu(int num)
parent
=
&
sysfs_nodes
[
cpu_to_node
(
num
)];
#endif
/* CONFIG_NUMA */
#ifdef CONFIG_ACPI_BOOT
/*
* If CPEI cannot be re-targetted, and this is
* CPEI target, then dont create the control file
*/
if
(
!
can_cpei_retarget
()
&&
is_cpu_cpei_target
(
num
))
sysfs_cpus
[
num
].
cpu
.
no_control
=
1
;
#endif
return
register_cpu
(
&
sysfs_cpus
[
num
].
cpu
,
num
,
parent
);
}
...
...
arch/x86_64/ia32/syscall32.c
浏览文件 @
076fb01e
...
...
@@ -57,6 +57,7 @@ int syscall32_setup_pages(struct linux_binprm *bprm, int exstack)
int
npages
=
(
VSYSCALL32_END
-
VSYSCALL32_BASE
)
>>
PAGE_SHIFT
;
struct
vm_area_struct
*
vma
;
struct
mm_struct
*
mm
=
current
->
mm
;
int
ret
;
vma
=
kmem_cache_alloc
(
vm_area_cachep
,
SLAB_KERNEL
);
if
(
!
vma
)
...
...
@@ -78,7 +79,11 @@ int syscall32_setup_pages(struct linux_binprm *bprm, int exstack)
vma
->
vm_mm
=
mm
;
down_write
(
&
mm
->
mmap_sem
);
insert_vm_struct
(
mm
,
vma
);
if
((
ret
=
insert_vm_struct
(
mm
,
vma
)))
{
up_write
(
&
mm
->
mmap_sem
);
kmem_cache_free
(
vm_area_cachep
,
vma
);
return
ret
;
}
mm
->
total_vm
+=
npages
;
up_write
(
&
mm
->
mmap_sem
);
return
0
;
...
...
drivers/mtd/nand/nand_base.c
浏览文件 @
076fb01e
...
...
@@ -59,7 +59,7 @@
* The AG-AND chips have nice features for speed improvement,
* which are not supported yet. Read / program 4 pages in one go.
*
* $Id: nand_base.c,v 1.14
6 2005/06/17 15:02
:06 gleixner Exp $
* $Id: nand_base.c,v 1.14
7 2005/07/15 07:18
:06 gleixner Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
...
...
@@ -1409,16 +1409,6 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
thislen
=
min_t
(
int
,
thislen
,
len
);
this
->
read_buf
(
mtd
,
&
buf
[
i
],
thislen
);
i
+=
thislen
;
/* Apply delay or wait for ready/busy pin
* Do this before the AUTOINCR check, so no problems
* arise if a chip which does auto increment
* is marked as NOAUTOINCR by the board driver.
*/
if
(
!
this
->
dev_ready
)
udelay
(
this
->
chip_delay
);
else
nand_wait_ready
(
mtd
);
/* Read more ? */
if
(
i
<
len
)
{
...
...
@@ -1432,6 +1422,16 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
this
->
select_chip
(
mtd
,
chipnr
);
}
/* Apply delay or wait for ready/busy pin
* Do this before the AUTOINCR check, so no problems
* arise if a chip which does auto increment
* is marked as NOAUTOINCR by the board driver.
*/
if
(
!
this
->
dev_ready
)
udelay
(
this
->
chip_delay
);
else
nand_wait_ready
(
mtd
);
/* Check, if the chip supports auto page increment
* or if we have hit a block boundary.
*/
...
...
drivers/mtd/nand/nand_bbt.c
浏览文件 @
076fb01e
...
...
@@ -6,7 +6,7 @@
*
* Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
*
* $Id: nand_bbt.c,v 1.3
3 2005/06/14 15:47:56
gleixner Exp $
* $Id: nand_bbt.c,v 1.3
5 2005/07/15 13:53:47
gleixner Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
...
...
@@ -109,24 +109,21 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des
/**
* check_short_pattern - [GENERIC] check if a pattern is in the buffer
* @buf: the buffer to search
* @len: the length of buffer to search
* @paglen: the pagelength
* @td: search pattern descriptor
*
* Check for a pattern at the given place. Used to search bad block
* tables and good / bad block identifiers. Same as check_pattern, but
* no optional empty check and the pattern is expected to start
* at offset 0.
* no optional empty check
*
*/
static
int
check_short_pattern
(
uint8_t
*
buf
,
int
len
,
int
paglen
,
struct
nand_bbt_descr
*
td
)
static
int
check_short_pattern
(
uint8_t
*
buf
,
struct
nand_bbt_descr
*
td
)
{
int
i
;
uint8_t
*
p
=
buf
;
/* Compare the pattern */
for
(
i
=
0
;
i
<
td
->
len
;
i
++
)
{
if
(
p
[
i
]
!=
td
->
pattern
[
i
])
if
(
p
[
td
->
offs
+
i
]
!=
td
->
pattern
[
i
])
return
-
1
;
}
return
0
;
...
...
@@ -337,13 +334,14 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
if
(
!
(
bd
->
options
&
NAND_BBT_SCANEMPTY
))
{
size_t
retlen
;
/* No need to read pages fully, just read required OOB bytes */
ret
=
mtd
->
read_oob
(
mtd
,
from
+
j
*
mtd
->
oobblock
+
bd
->
offs
,
readlen
,
&
retlen
,
&
buf
[
0
]);
/* Read the full oob until read_oob is fixed to
* handle single byte reads for 16 bit buswidth */
ret
=
mtd
->
read_oob
(
mtd
,
from
+
j
*
mtd
->
oobblock
,
mtd
->
oobsize
,
&
retlen
,
buf
);
if
(
ret
)
return
ret
;
if
(
check_short_pattern
(
&
buf
[
j
*
scanlen
],
scanlen
,
mtd
->
oobblock
,
bd
))
{
if
(
check_short_pattern
(
buf
,
bd
))
{
this
->
bbt
[
i
>>
3
]
|=
0x03
<<
(
i
&
0x6
);
printk
(
KERN_WARNING
"Bad eraseblock %d at 0x%08x
\n
"
,
i
>>
1
,
(
unsigned
int
)
from
);
...
...
drivers/serial/crisv10.c
浏览文件 @
076fb01e
...
...
@@ -426,8 +426,6 @@
static
char
*
serial_version
=
"$Revision: 1.25 $"
;
#include <linux/config.h>
#include <linux/version.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/signal.h>
...
...
drivers/serial/icom.c
浏览文件 @
076fb01e
...
...
@@ -25,7 +25,6 @@
#define SERIAL_DO_RESTART
#include <linux/module.h>
#include <linux/config.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/signal.h>
...
...
drivers/serial/jsm/jsm.h
浏览文件 @
076fb01e
...
...
@@ -28,7 +28,6 @@
#define __JSM_DRIVER_H
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/types.h>
/* To pick up the varions Linux types */
#include <linux/tty.h>
#include <linux/serial_core.h>
...
...
fs/jffs2/erase.c
浏览文件 @
076fb01e
...
...
@@ -7,7 +7,7 @@
*
* For licensing information, see the file 'LICENCE' in this directory.
*
* $Id: erase.c,v 1.
76 2005/05/03 15:11:40 dedekind
Exp $
* $Id: erase.c,v 1.
80 2005/07/14 19:46:24 joern
Exp $
*
*/
...
...
@@ -300,100 +300,86 @@ static void jffs2_free_all_node_refs(struct jffs2_sb_info *c, struct jffs2_erase
jeb
->
last_node
=
NULL
;
}
static
void
jffs2_mark_erased_block
(
struct
jffs2_sb_info
*
c
,
struct
jffs2_eraseblock
*
jeb
)
static
int
jffs2_block_check_erase
(
struct
jffs2_sb_info
*
c
,
struct
jffs2_eraseblock
*
jeb
,
uint32_t
*
bad_offset
)
{
struct
jffs2_raw_node_ref
*
marker_ref
=
NULL
;
u
nsigned
char
*
ebuf
;
void
*
ebuf
;
u
int32_t
ofs
;
size_t
retlen
;
int
ret
;
uint32_t
bad_offset
;
if
((
!
jffs2_cleanmarker_oob
(
c
))
&&
(
c
->
cleanmarker_size
>
0
))
{
marker_ref
=
jffs2_alloc_raw_node_ref
();
if
(
!
marker_ref
)
{
printk
(
KERN_WARNING
"Failed to allocate raw node ref for clean marker
\n
"
);
/* Stick it back on the list from whence it came and come back later */
jffs2_erase_pending_trigger
(
c
);
spin_lock
(
&
c
->
erase_completion_lock
);
list_add
(
&
jeb
->
list
,
&
c
->
erase_complete_list
);
spin_unlock
(
&
c
->
erase_completion_lock
);
return
;
}
}
int
ret
=
-
EIO
;
ebuf
=
kmalloc
(
PAGE_SIZE
,
GFP_KERNEL
);
if
(
!
ebuf
)
{
printk
(
KERN_WARNING
"Failed to allocate page buffer for verifying erase at 0x%08x.
Assuming it worked
\n
"
,
jeb
->
offset
);
}
else
{
uint32_t
ofs
=
jeb
->
offset
;
printk
(
KERN_WARNING
"Failed to allocate page buffer for verifying erase at 0x%08x.
Refiling
\n
"
,
jeb
->
offset
);
return
-
EAGAIN
;
}
D1
(
printk
(
KERN_DEBUG
"Verifying erase at 0x%08x
\n
"
,
jeb
->
offset
));
while
(
ofs
<
jeb
->
offset
+
c
->
sector_size
)
{
uint32_t
readlen
=
min
((
uint32_t
)
PAGE_SIZE
,
jeb
->
offset
+
c
->
sector_size
-
ofs
);
int
i
;
D1
(
printk
(
KERN_DEBUG
"Verifying erase at 0x%08x
\n
"
,
jeb
->
offset
));
bad_offset
=
ofs
;
for
(
ofs
=
jeb
->
offset
;
ofs
<
jeb
->
offset
+
c
->
sector_size
;
)
{
uint32_t
readlen
=
min
((
uint32_t
)
PAGE_SIZE
,
jeb
->
offset
+
c
->
sector_size
-
ofs
);
int
i
;
ret
=
c
->
mtd
->
read
(
c
->
mtd
,
ofs
,
readlen
,
&
retlen
,
ebuf
)
;
*
bad_offset
=
ofs
;
if
(
ret
)
{
printk
(
KERN_WARNING
"Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list
\n
"
,
ofs
,
ret
);
goto
bad
;
}
if
(
retlen
!=
readlen
)
{
printk
(
KERN_WARNING
"Short read from newly-erased block at 0x%08x. Wanted %d, got %zd
\n
"
,
ofs
,
readlen
,
retlen
);
goto
bad
;
}
for
(
i
=
0
;
i
<
readlen
;
i
+=
sizeof
(
unsigned
long
))
{
/* It's OK. We know it's properly aligned */
unsigned
long
datum
=
*
(
unsigned
long
*
)(
&
ebuf
[
i
]);
if
(
datum
+
1
)
{
bad_offset
+=
i
;
printk
(
KERN_WARNING
"Newly-erased block contained word 0x%lx at offset 0x%08x
\n
"
,
datum
,
bad_offset
);
bad:
if
((
!
jffs2_cleanmarker_oob
(
c
))
&&
(
c
->
cleanmarker_size
>
0
))
jffs2_free_raw_node_ref
(
marker_ref
);
kfree
(
ebuf
);
bad2:
spin_lock
(
&
c
->
erase_completion_lock
);
/* Stick it on a list (any list) so
erase_failed can take it right off
again. Silly, but shouldn't happen
often. */
list_add
(
&
jeb
->
list
,
&
c
->
erasing_list
);
spin_unlock
(
&
c
->
erase_completion_lock
);
jffs2_erase_failed
(
c
,
jeb
,
bad_offset
);
return
;
}
ret
=
jffs2_flash_read
(
c
,
ofs
,
readlen
,
&
retlen
,
ebuf
);
if
(
ret
)
{
printk
(
KERN_WARNING
"Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list
\n
"
,
ofs
,
ret
);
goto
fail
;
}
if
(
retlen
!=
readlen
)
{
printk
(
KERN_WARNING
"Short read from newly-erased block at 0x%08x. Wanted %d, got %zd
\n
"
,
ofs
,
readlen
,
retlen
);
goto
fail
;
}
for
(
i
=
0
;
i
<
readlen
;
i
+=
sizeof
(
unsigned
long
))
{
/* It's OK. We know it's properly aligned */
unsigned
long
*
datum
=
ebuf
+
i
;
if
(
*
datum
+
1
)
{
*
bad_offset
+=
i
;
printk
(
KERN_WARNING
"Newly-erased block contained word 0x%lx at offset 0x%08x
\n
"
,
*
datum
,
*
bad_offset
);
goto
fail
;
}
ofs
+=
readlen
;
cond_resched
();
}
kfree
(
ebuf
);
ofs
+=
readlen
;
cond_resched
();
}
ret
=
0
;
fail:
kfree
(
ebuf
);
return
ret
;
}
bad_offset
=
jeb
->
offset
;
static
void
jffs2_mark_erased_block
(
struct
jffs2_sb_info
*
c
,
struct
jffs2_eraseblock
*
jeb
)
{
struct
jffs2_raw_node_ref
*
marker_ref
=
NULL
;
size_t
retlen
;
int
ret
;
uint32_t
bad_offset
;
switch
(
jffs2_block_check_erase
(
c
,
jeb
,
&
bad_offset
))
{
case
-
EAGAIN
:
goto
refile
;
case
-
EIO
:
goto
filebad
;
}
/* Write the erase complete marker */
D1
(
printk
(
KERN_DEBUG
"Writing erased marker to block at 0x%08x
\n
"
,
jeb
->
offset
));
if
(
jffs2_cleanmarker_oob
(
c
))
{
bad_offset
=
jeb
->
offset
;
if
(
jffs2_write_nand_cleanmarker
(
c
,
jeb
))
goto
bad2
;
jeb
->
first_node
=
jeb
->
last_node
=
NULL
;
/* Cleanmarker in oob area or no cleanmarker at all ? */
if
(
jffs2_cleanmarker_oob
(
c
)
||
c
->
cleanmarker_size
==
0
)
{
jeb
->
free_size
=
c
->
sector_size
;
jeb
->
used_size
=
0
;
jeb
->
dirty_size
=
0
;
jeb
->
wasted_size
=
0
;
}
else
if
(
c
->
cleanmarker_size
==
0
)
{
jeb
->
first_node
=
jeb
->
last_node
=
NULL
;
if
(
jffs2_cleanmarker_oob
(
c
))
{
if
(
jffs2_write_nand_cleanmarker
(
c
,
jeb
))
goto
filebad
;
}
jeb
->
first_node
=
jeb
->
last_node
=
NULL
;
jeb
->
free_size
=
c
->
sector_size
;
jeb
->
used_size
=
0
;
jeb
->
dirty_size
=
0
;
jeb
->
wasted_size
=
0
;
}
else
{
struct
kvec
vecs
[
1
];
struct
jffs2_unknown_node
marker
=
{
.
magic
=
cpu_to_je16
(
JFFS2_MAGIC_BITMASK
),
...
...
@@ -401,21 +387,28 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
.
totlen
=
cpu_to_je32
(
c
->
cleanmarker_size
)
};
marker_ref
=
jffs2_alloc_raw_node_ref
();
if
(
!
marker_ref
)
{
printk
(
KERN_WARNING
"Failed to allocate raw node ref for clean marker. Refiling
\n
"
);
goto
refile
;
}
marker
.
hdr_crc
=
cpu_to_je32
(
crc32
(
0
,
&
marker
,
sizeof
(
struct
jffs2_unknown_node
)
-
4
));
vecs
[
0
].
iov_base
=
(
unsigned
char
*
)
&
marker
;
vecs
[
0
].
iov_len
=
sizeof
(
marker
);
ret
=
jffs2_flash_direct_writev
(
c
,
vecs
,
1
,
jeb
->
offset
,
&
retlen
);
if
(
ret
)
{
printk
(
KERN_WARNING
"Write clean marker to block at 0x%08x failed: %d
\n
"
,
jeb
->
offset
,
ret
);
goto
bad2
;
}
if
(
retlen
!=
sizeof
(
marker
))
{
printk
(
KERN_WARNING
"Short write to newly-erased block at 0x%08x: Wanted %zd, got %zd
\n
"
,
jeb
->
offset
,
sizeof
(
marker
),
retlen
);
goto
bad2
;
if
(
ret
||
retlen
!=
sizeof
(
marker
))
{
if
(
ret
)
printk
(
KERN_WARNING
"Write clean marker to block at 0x%08x failed: %d
\n
"
,
jeb
->
offset
,
ret
);
else
printk
(
KERN_WARNING
"Short write to newly-erased block at 0x%08x: Wanted %zd, got %zd
\n
"
,
jeb
->
offset
,
sizeof
(
marker
),
retlen
);
jffs2_free_raw_node_ref
(
marker_ref
);
goto
filebad
;
}
marker_ref
->
next_in_ino
=
NULL
;
...
...
@@ -444,5 +437,22 @@ static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseb
c
->
nr_free_blocks
++
;
spin_unlock
(
&
c
->
erase_completion_lock
);
wake_up
(
&
c
->
erase_wait
);
}
return
;
filebad:
spin_lock
(
&
c
->
erase_completion_lock
);
/* Stick it on a list (any list) so erase_failed can take it
right off again. Silly, but shouldn't happen often. */
list_add
(
&
jeb
->
list
,
&
c
->
erasing_list
);
spin_unlock
(
&
c
->
erase_completion_lock
);
jffs2_erase_failed
(
c
,
jeb
,
bad_offset
);
return
;
refile:
/* Stick it back on the list from whence it came and come back later */
jffs2_erase_pending_trigger
(
c
);
spin_lock
(
&
c
->
erase_completion_lock
);
list_add
(
&
jeb
->
list
,
&
c
->
erase_complete_list
);
spin_unlock
(
&
c
->
erase_completion_lock
);
return
;
}
fs/ntfs/ChangeLog
浏览文件 @
076fb01e
ToDo/Notes:
- Find and fix bugs.
- Checkpoint or disable the user space journal ($UsnJrnl).
- In between ntfs_prepare/commit_write, need exclusion between
simultaneous file extensions.
Need perhaps an NInoResizeUnderway()
flag which we can set in ntfs_prepare_write() and clear again in
ntfs_commit_write(). Just have to be careful in readpage/writepage,
as well as in truncate, that we play nice... We might need to have
a data_size field in the ntfs_inode to store the real attribute
length.
Also need to be careful with initialized_size extention in
simultaneous file extensions.
This is given to us by holding i_sem
on the inode. The only places in the kernel when a file is resized
are prepare/commit write and truncate for both of which i_sem is
held. Just have to be careful in readpage/writepage and all other
helpers not running under i_sem that we play nice...
Also need to be careful with initialized_size extention in
ntfs_prepare_write. Basically, just be _very_ careful in this code...
OTOH, perhaps i_sem, which is held accross generic_file_write is
sufficient for synchronisation here. We then just need to make sure
ntfs_readpage/writepage/truncate interoperate properly with us.
UPDATE: The above is all ok as it is due to i_sem held. The only
thing that needs to be checked is ntfs_writepage() which does not
hold i_sem. It cannot change i_size but it needs to cope with a
concurrent i_size change.
UPDATE: The only things that need to be checked are read/writepage
which do not hold i_sem. Note writepage cannot change i_size but it
needs to cope with a concurrent i_size change, just like readpage.
Also both need to cope with concurrent changes to the other sizes,
i.e. initialized/allocated/compressed size, as well.
- Implement mft.c::sync_mft_mirror_umount(). We currently will just
leave the volume dirty on umount if the final iput(vol->mft_ino)
causes a write of any mirrored mft records due to the mft mirror
...
...
@@ -25,12 +22,158 @@ ToDo/Notes:
- Enable the code for setting the NT4 compatibility flag when we start
making NTFS 1.2 specific modifications.
2.1.23-WIP
2.1.23 - Implement extension of resident files and make writing safe as well as
many bug fixes, cleanups, and enhancements...
- Add printk rate limiting for ntfs_warning() and ntfs_error() when
compiled without debug. This avoids a possible denial of service
attack. Thanks to Carl-Daniel Hailfinger from SuSE for pointing this
out.
- Fix compilation warnings on ia64. (Randy Dunlap)
- Use i_size_{read,write}() instead of reading i_size by hand and cache
the value where apropriate.
- Add size_lock to the ntfs_inode structure. This is an rw spinlock
and it locks against access to the inode sizes. Note, ->size_lock
is also accessed from irq context so you must use the _irqsave and
_irqrestore lock and unlock functions, respectively. Protect all
accesses to allocated_size, initialized_size, and compressed_size.
- Minor optimization to fs/ntfs/super.c::ntfs_statfs() and its helpers.
- Implement extension of resident files in the regular file write code
paths (fs/ntfs/aops.c::ntfs_{prepare,commit}_write()). At present
this only works until the data attribute becomes too big for the mft
record after which we abort the write returning -EOPNOTSUPP from
ntfs_prepare_write().
- Add disable_sparse mount option together with a per volume sparse
enable bit which is set appropriately and a per inode sparse disable
bit which is preset on some system file inodes as appropriate.
- Enforce that sparse support is disabled on NTFS volumes pre 3.0.
- Fix a bug in fs/ntfs/runlist.c::ntfs_mapping_pairs_decompress() in
the creation of the unmapped runlist element for the base attribute
extent.
- Split ntfs_map_runlist() into ntfs_map_runlist() and a non-locking
helper ntfs_map_runlist_nolock() which is used by ntfs_map_runlist().
This allows us to map runlist fragments with the runlist lock already
held without having to drop and reacquire it around the call. Adapt
all callers.
- Change ntfs_find_vcn() to ntfs_find_vcn_nolock() which takes a locked
runlist. This allows us to find runlist elements with the runlist
lock already held without having to drop and reacquire it around the
call. Adapt all callers.
- Change time to u64 in time.h::ntfs2utc() as it otherwise generates a
warning in the do_div() call on sparc32. Thanks to Meelis Roos for
the report and analysis of the warning.
- Fix a nasty runlist merge bug when merging two holes.
- Set the ntfs_inode->allocated_size to the real allocated size in the
mft record for resident attributes (fs/ntfs/inode.c).
- Small readability cleanup to use "a" instead of "ctx->attr"
everywhere (fs/ntfs/inode.c).
- Make fs/ntfs/namei.c::ntfs_get_{parent,dentry} static and move the
definition of ntfs_export_ops from fs/ntfs/super.c to namei.c. Also,
declare ntfs_export_ops in fs/ntfs/ntfs.h.
- Correct sparse file handling. The compressed values need to be
checked and set in the ntfs inode as done for compressed files and
the compressed size needs to be used for vfs inode->i_blocks instead
of the allocated size, again, as done for compressed files.
- Add AT_EA in addition to AT_DATA to whitelist for being allowed to be
non-resident in fs/ntfs/attrib.c::ntfs_attr_can_be_non_resident().
- Add fs/ntfs/attrib.c::ntfs_attr_vcn_to_lcn_nolock() used by the new
write code.
- Fix bug in fs/ntfs/attrib.c::ntfs_find_vcn_nolock() where after
dropping the read lock and taking the write lock we were not checking
whether someone else did not already do the work we wanted to do.
- Rename fs/ntfs/attrib.c::ntfs_find_vcn_nolock() to
ntfs_attr_find_vcn_nolock() and update all callers.
- Add fs/ntfs/attrib.[hc]::ntfs_attr_make_non_resident().
- Fix sign of various error return values to be negative in
fs/ntfs/lcnalloc.c.
- Modify ->readpage and ->writepage (fs/ntfs/aops.c) so they detect and
handle the case where an attribute is converted from resident to
non-resident by a concurrent file write.
- Remove checks for NULL before calling kfree() since kfree() does the
checking itself. (Jesper Juhl)
- Some utilities modify the boot sector but do not update the checksum.
Thus, relax the checking in fs/ntfs/super.c::is_boot_sector_ntfs() to
only emit a warning when the checksum is incorrect rather than
refusing the mount. Thanks to Bernd Casimir for pointing this
problem out.
- Update attribute definition handling.
- Add NTFS_MAX_CLUSTER_SIZE and NTFS_MAX_PAGES_PER_CLUSTER constants.
- Use NTFS_MAX_CLUSTER_SIZE in super.c instead of hard coding 0x10000.
- Use MAX_BUF_PER_PAGE instead of variable sized array allocation for
better code generation and one less sparse warning in fs/ntfs/aops.c.
- Remove spurious void pointer casts from fs/ntfs/. (Pekka Enberg)
- Use C99 style structure initialization after memory allocation where
possible (fs/ntfs/{attrib.c,index.c,super.c}). Thanks to Al Viro and
Pekka Enberg.
- Stamp the transaction log ($UsnJrnl), aka user space journal, if it
is active on the volume and we are mounting read-write or remounting
from read-only to read-write.
- Fix a bug in address space operations error recovery code paths where
if the runlist was not mapped at all and a mapping error occured we
would leave the runlist locked on exit to the function so that the
next access to the same file would try to take the lock and deadlock.
- Detect the case when Windows has been suspended to disk on the volume
to be mounted and if this is the case do not allow (re)mounting
read-write. This is done by parsing hiberfil.sys if present.
- Fix several occurences of a bug where we would perform 'var & ~const'
with a 64-bit variable and a int, i.e. 32-bit, constant. This causes
the higher order 32-bits of the 64-bit variable to be zeroed. To fix
this cast the 'const' to the same 64-bit type as 'var'.
- Change the runlist terminator of the newly allocated cluster(s) to
LCN_ENOENT in ntfs_attr_make_non_resident(). Otherwise the runlist
code gets confused.
- Add an extra parameter @last_vcn to ntfs_get_size_for_mapping_pairs()
and ntfs_mapping_pairs_build() to allow the runlist encoding to be
partial which is desirable when filling holes in sparse attributes.
Update all callers.
- Change ntfs_map_runlist_nolock() to only decompress the mapping pairs
if the requested vcn is inside it. Otherwise we get into problems
when we try to map an out of bounds vcn because we then try to map
the already mapped runlist fragment which causes
ntfs_mapping_pairs_decompress() to fail and return error. Update
ntfs_attr_find_vcn_nolock() accordingly.
- Fix a nasty deadlock that appeared in recent kernels.
The situation: VFS inode X on a mounted ntfs volume is dirty. For
same inode X, the ntfs_inode is dirty and thus corresponding on-disk
inode, i.e. mft record, which is in a dirty PAGE_CACHE_PAGE belonging
to the table of inodes, i.e. $MFT, inode 0.
What happens:
Process 1: sys_sync()/umount()/whatever... calls
__sync_single_inode() for $MFT -> do_writepages() -> write_page for
the dirty page containing the on-disk inode X, the page is now locked
-> ntfs_write_mst_block() which clears PageUptodate() on the page to
prevent anyone else getting hold of it whilst it does the write out.
This is necessary as the on-disk inode needs "fixups" applied before
the write to disk which are removed again after the write and
PageUptodate is then set again. It then analyses the page looking
for dirty on-disk inodes and when it finds one it calls
ntfs_may_write_mft_record() to see if it is safe to write this
on-disk inode. This then calls ilookup5() to check if the
corresponding VFS inode is in icache(). This in turn calls ifind()
which waits on the inode lock via wait_on_inode whilst holding the
global inode_lock.
Process 2: pdflush results in a call to __sync_single_inode for the
same VFS inode X on the ntfs volume. This locks the inode (I_LOCK)
then calls write-inode -> ntfs_write_inode -> map_mft_record() ->
read_cache_page() for the page (in page cache of table of inodes
$MFT, inode 0) containing the on-disk inode. This page has
PageUptodate() clear because of Process 1 (see above) so
read_cache_page() blocks when it tries to take the page lock for the
page so it can call ntfs_read_page().
Thus Process 1 is holding the page lock on the page containing the
on-disk inode X and it is waiting on the inode X to be unlocked in
ifind() so it can write the page out and then unlock the page.
And Process 2 is holding the inode lock on inode X and is waiting for
the page to be unlocked so it can call ntfs_readpage() or discover
that Process 1 set PageUptodate() again and use the page.
Thus we have a deadlock due to ifind() waiting on the inode lock.
The solution: The fix is to use the newly introduced
ilookup5_nowait() which does not wait on the inode's lock and hence
avoids the deadlock. This is safe as we do not care about the VFS
inode and only use the fact that it is in the VFS inode cache and the
fact that the vfs and ntfs inodes are one struct in memory to find
the ntfs inode in memory if present. Also, the ntfs inode has its
own locking so it does not matter if the vfs inode is locked.
2.1.22 - Many bug and race fixes and error handling improvements.
...
...
@@ -1037,7 +1180,7 @@ tng-0.0.8 - 08/03/2002 - Now using BitKeeper, http://linux-ntfs.bkbits.net/
- Further runlist merging work. (Richard Russon)
- Backwards compatibility for gcc-2.95. (Richard Russon)
- Update to kernel 2.5.5-pre1 and rediff the now tiny patch.
- Convert to new file
system declaration using ->ntfs_get_sb() and
- Convert to new filesystem declaration using ->ntfs_get_sb() and
replacing ntfs_read_super() with ntfs_fill_super().
- Set s_maxbytes to MAX_LFS_FILESIZE to avoid page cache page index
overflow on 32-bit architectures.
...
...
@@ -1333,7 +1476,7 @@ tng-0.0.1 - The first useful version.
The driver is now actually useful! Yey. (-: It undoubtedly has got bugs
though and it doesn't implement accesssing compressed files yet. Also,
accessing files with attribute list attributes is not implemented yet
either. But for small or simple file
systems it should work and allow
either. But for small or simple filesystems it should work and allow
you to list directories, use stat on directory entries and the file
system, open, read, mmap and llseek around in files. A big mile stone
has been reached!
...
...
@@ -1341,7 +1484,7 @@ tng-0.0.1 - The first useful version.
tng-0.0.0 - Initial version tag.
Initial driver implementation. The driver can mount and umount simple
NTFS file
systems (i.e. ones without attribute lists in the system
NTFS filesystems (i.e. ones without attribute lists in the system
files). If the mount fails there might be problems in the error handling
code paths, so be warned. Otherwise it seems to be loading the system
files nicely and the mft record read mapping/unmapping seems to be
...
...
fs/ntfs/Makefile
浏览文件 @
076fb01e
...
...
@@ -6,7 +6,7 @@ ntfs-objs := aops.o attrib.o collate.o compress.o debug.o dir.o file.o \
index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o
\
unistr.o upcase.o
EXTRA_CFLAGS
=
-DNTFS_VERSION
=
\"
2.1.2
2
\"
EXTRA_CFLAGS
=
-DNTFS_VERSION
=
\"
2.1.2
3
\"
ifeq
($(CONFIG_NTFS_DEBUG),y)
EXTRA_CFLAGS
+=
-DDEBUG
...
...
@@ -15,5 +15,5 @@ endif
ifeq
($(CONFIG_NTFS_RW),y)
EXTRA_CFLAGS
+=
-DNTFS_RW
ntfs-objs
+=
bitmap.o lcnalloc.o logfile.o quota.o
ntfs-objs
+=
bitmap.o lcnalloc.o logfile.o quota.o
usnjrnl.o
endif
fs/ntfs/aops.c
浏览文件 @
076fb01e
...
...
@@ -2,7 +2,7 @@
* aops.c - NTFS kernel address space operations and page cache handling.
* Part of the Linux-NTFS project.
*
* Copyright (c) 2001-200
4
Anton Altaparmakov
* Copyright (c) 2001-200
5
Anton Altaparmakov
* Copyright (c) 2002 Richard Russon
*
* This program/include file is free software; you can redistribute it and/or
...
...
@@ -66,19 +66,22 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate)
ni
=
NTFS_I
(
page
->
mapping
->
host
);
if
(
likely
(
uptodate
))
{
s64
file_ofs
;
s64
file_ofs
,
initialized_size
;
set_buffer_uptodate
(
bh
);
file_ofs
=
((
s64
)
page
->
index
<<
PAGE_CACHE_SHIFT
)
+
bh_offset
(
bh
);
read_lock_irqsave
(
&
ni
->
size_lock
,
flags
);
initialized_size
=
ni
->
initialized_size
;
read_unlock_irqrestore
(
&
ni
->
size_lock
,
flags
);
/* Check for the current buffer head overflowing. */
if
(
file_ofs
+
bh
->
b_size
>
ni
->
initialized_size
)
{
if
(
file_ofs
+
bh
->
b_size
>
initialized_size
)
{
char
*
addr
;
int
ofs
=
0
;
if
(
file_ofs
<
ni
->
initialized_size
)
ofs
=
ni
->
initialized_size
-
file_ofs
;
if
(
file_ofs
<
initialized_size
)
ofs
=
initialized_size
-
file_ofs
;
addr
=
kmap_atomic
(
page
,
KM_BIO_SRC_IRQ
);
memset
(
addr
+
bh_offset
(
bh
)
+
ofs
,
0
,
bh
->
b_size
-
ofs
);
flush_dcache_page
(
page
);
...
...
@@ -132,7 +135,7 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate)
i
*
rec_size
),
rec_size
);
flush_dcache_page
(
page
);
kunmap_atomic
(
addr
,
KM_BIO_SRC_IRQ
);
if
(
likely
(
!
PageError
(
page
)
&&
page_uptodate
))
if
(
likely
(
page_uptodate
&&
!
PageError
(
page
)
))
SetPageUptodate
(
page
);
}
unlock_page
(
page
);
...
...
@@ -168,6 +171,7 @@ static int ntfs_read_block(struct page *page)
runlist_element
*
rl
;
struct
buffer_head
*
bh
,
*
head
,
*
arr
[
MAX_BUF_PER_PAGE
];
sector_t
iblock
,
lblock
,
zblock
;
unsigned
long
flags
;
unsigned
int
blocksize
,
vcn_ofs
;
int
i
,
nr
;
unsigned
char
blocksize_bits
;
...
...
@@ -190,8 +194,10 @@ static int ntfs_read_block(struct page *page)
}
iblock
=
(
s64
)
page
->
index
<<
(
PAGE_CACHE_SHIFT
-
blocksize_bits
);
read_lock_irqsave
(
&
ni
->
size_lock
,
flags
);
lblock
=
(
ni
->
allocated_size
+
blocksize
-
1
)
>>
blocksize_bits
;
zblock
=
(
ni
->
initialized_size
+
blocksize
-
1
)
>>
blocksize_bits
;
read_unlock_irqrestore
(
&
ni
->
size_lock
,
flags
);
/* Loop through all the buffers in the page. */
rl
=
NULL
;
...
...
@@ -258,7 +264,8 @@ static int ntfs_read_block(struct page *page)
goto
lock_retry_remap
;
rl
=
NULL
;
lcn
=
err
;
}
}
else
if
(
!
rl
)
up_read
(
&
ni
->
runlist
.
lock
);
/* Hard error, zero out region. */
bh
->
b_blocknr
=
-
1
;
SetPageError
(
page
);
...
...
@@ -341,14 +348,15 @@ static int ntfs_read_block(struct page *page)
*/
static
int
ntfs_readpage
(
struct
file
*
file
,
struct
page
*
page
)
{
loff_t
i_size
;
ntfs_inode
*
ni
,
*
base_ni
;
u8
*
kaddr
;
ntfs_attr_search_ctx
*
ctx
;
MFT_RECORD
*
mrec
;
unsigned
long
flags
;
u32
attr_len
;
int
err
=
0
;
retry_readpage:
BUG_ON
(
!
PageLocked
(
page
));
/*
* This can potentially happen because we clear PageUptodate() during
...
...
@@ -383,9 +391,9 @@ static int ntfs_readpage(struct file *file, struct page *page)
* Attribute is resident, implying it is not compressed or encrypted.
* This also means the attribute is smaller than an mft record and
* hence smaller than a page, so can simply zero out any pages with
* index above 0.
We can also do this if the file size is 0.
* index above 0.
*/
if
(
unlikely
(
page
->
index
>
0
||
!
i_size_read
(
VFS_I
(
ni
))
))
{
if
(
unlikely
(
page
->
index
>
0
))
{
kaddr
=
kmap_atomic
(
page
,
KM_USER0
);
memset
(
kaddr
,
0
,
PAGE_CACHE_SIZE
);
flush_dcache_page
(
page
);
...
...
@@ -402,6 +410,14 @@ static int ntfs_readpage(struct file *file, struct page *page)
err
=
PTR_ERR
(
mrec
);
goto
err_out
;
}
/*
* If a parallel write made the attribute non-resident, drop the mft
* record and retry the readpage.
*/
if
(
unlikely
(
NInoNonResident
(
ni
)))
{
unmap_mft_record
(
base_ni
);
goto
retry_readpage
;
}
ctx
=
ntfs_attr_get_search_ctx
(
base_ni
,
mrec
);
if
(
unlikely
(
!
ctx
))
{
err
=
-
ENOMEM
;
...
...
@@ -412,9 +428,10 @@ static int ntfs_readpage(struct file *file, struct page *page)
if
(
unlikely
(
err
))
goto
put_unm_err_out
;
attr_len
=
le32_to_cpu
(
ctx
->
attr
->
data
.
resident
.
value_length
);
i_size
=
i_size_read
(
VFS_I
(
ni
));
if
(
unlikely
(
attr_len
>
i_size
))
attr_len
=
i_size
;
read_lock_irqsave
(
&
ni
->
size_lock
,
flags
);
if
(
unlikely
(
attr_len
>
ni
->
initialized_size
))
attr_len
=
ni
->
initialized_size
;
read_unlock_irqrestore
(
&
ni
->
size_lock
,
flags
);
kaddr
=
kmap_atomic
(
page
,
KM_USER0
);
/* Copy the data to the page. */
memcpy
(
kaddr
,
(
u8
*
)
ctx
->
attr
+
...
...
@@ -463,12 +480,15 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
{
VCN
vcn
;
LCN
lcn
;
s64
initialized_size
;
loff_t
i_size
;
sector_t
block
,
dblock
,
iblock
;
struct
inode
*
vi
;
ntfs_inode
*
ni
;
ntfs_volume
*
vol
;
runlist_element
*
rl
;
struct
buffer_head
*
bh
,
*
head
;
unsigned
long
flags
;
unsigned
int
blocksize
,
vcn_ofs
;
int
err
;
BOOL
need_end_writeback
;
...
...
@@ -510,11 +530,16 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
/* The first block in the page. */
block
=
(
s64
)
page
->
index
<<
(
PAGE_CACHE_SHIFT
-
blocksize_bits
);
read_lock_irqsave
(
&
ni
->
size_lock
,
flags
);
i_size
=
i_size_read
(
vi
);
initialized_size
=
ni
->
initialized_size
;
read_unlock_irqrestore
(
&
ni
->
size_lock
,
flags
);
/* The first out of bounds block for the data size. */
dblock
=
(
vi
->
i_size
+
blocksize
-
1
)
>>
blocksize_bits
;
dblock
=
(
i_size
+
blocksize
-
1
)
>>
blocksize_bits
;
/* The last (fully or partially) initialized block. */
iblock
=
ni
->
initialized_size
>>
blocksize_bits
;
iblock
=
initialized_size
>>
blocksize_bits
;
/*
* Be very careful. We have no exclusion from __set_page_dirty_buffers
...
...
@@ -559,7 +584,7 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
/* Make sure we have enough initialized size. */
if
(
unlikely
((
block
>=
iblock
)
&&
(
ni
->
initialized_size
<
vi
->
i_size
)))
{
(
initialized_size
<
i_size
)))
{
/*
* If this page is fully outside initialized size, zero
* out all pages between the current initialized size
...
...
@@ -666,7 +691,8 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc)
goto
lock_retry_remap
;
rl
=
NULL
;
lcn
=
err
;
}
}
else
if
(
!
rl
)
up_read
(
&
ni
->
runlist
.
lock
);
/* Failed to map the buffer, even after retrying. */
bh
->
b_blocknr
=
-
1
;
ntfs_error
(
vol
->
sb
,
"Failed to write to inode 0x%lx, "
...
...
@@ -801,17 +827,15 @@ static int ntfs_write_mst_block(struct page *page,
ntfs_inode
*
ni
=
NTFS_I
(
vi
);
ntfs_volume
*
vol
=
ni
->
vol
;
u8
*
kaddr
;
unsigned
char
bh_size_bits
=
vi
->
i_blkbits
;
unsigned
int
bh_size
=
1
<<
bh_size_bits
;
unsigned
int
rec_size
=
ni
->
itype
.
index
.
block_size
;
ntfs_inode
*
locked_nis
[
PAGE_CACHE_SIZE
/
rec_size
];
struct
buffer_head
*
bh
,
*
head
,
*
tbh
,
*
rec_start_bh
;
int
max_bhs
=
PAGE_CACHE_SIZE
/
bh_size
;
struct
buffer_head
*
bhs
[
max_bhs
];
struct
buffer_head
*
bhs
[
MAX_BUF_PER_PAGE
];
runlist_element
*
rl
;
int
i
,
nr_locked_nis
,
nr_recs
,
nr_bhs
,
bhs_per_rec
,
err
,
err2
;
unsigned
rec_size_bits
;
int
i
,
nr_locked_nis
,
nr_recs
,
nr_bhs
,
max_bhs
,
bhs_per_rec
,
err
,
err2
;
unsigned
bh_size
,
rec_size_bits
;
BOOL
sync
,
is_mft
,
page_is_dirty
,
rec_is_dirty
;
unsigned
char
bh_size_bits
;
ntfs_debug
(
"Entering for inode 0x%lx, attribute type 0x%x, page index "
"0x%lx."
,
vi
->
i_ino
,
ni
->
type
,
page
->
index
);
...
...
@@ -826,7 +850,11 @@ static int ntfs_write_mst_block(struct page *page,
*/
BUG_ON
(
!
(
is_mft
||
S_ISDIR
(
vi
->
i_mode
)
||
(
NInoAttr
(
ni
)
&&
ni
->
type
==
AT_INDEX_ALLOCATION
)));
bh_size_bits
=
vi
->
i_blkbits
;
bh_size
=
1
<<
bh_size_bits
;
max_bhs
=
PAGE_CACHE_SIZE
/
bh_size
;
BUG_ON
(
!
max_bhs
);
BUG_ON
(
max_bhs
>
MAX_BUF_PER_PAGE
);
/* Were we called for sync purposes? */
sync
=
(
wbc
->
sync_mode
==
WB_SYNC_ALL
);
...
...
@@ -846,7 +874,7 @@ static int ntfs_write_mst_block(struct page *page,
(
PAGE_CACHE_SHIFT
-
bh_size_bits
);
/* The first out of bounds block for the data size. */
dblock
=
(
vi
->
i_size
+
bh_size
-
1
)
>>
bh_size_bits
;
dblock
=
(
i_size_read
(
vi
)
+
bh_size
-
1
)
>>
bh_size_bits
;
rl
=
NULL
;
err
=
err2
=
nr_bhs
=
nr_recs
=
nr_locked_nis
=
0
;
...
...
@@ -858,6 +886,7 @@ static int ntfs_write_mst_block(struct page *page,
if
(
likely
(
block
<
rec_block
))
{
if
(
unlikely
(
block
>=
dblock
))
{
clear_buffer_dirty
(
bh
);
set_buffer_uptodate
(
bh
);
continue
;
}
/*
...
...
@@ -938,8 +967,11 @@ static int ntfs_write_mst_block(struct page *page,
if
(
err2
==
-
ENOMEM
)
page_is_dirty
=
TRUE
;
lcn
=
err2
;
}
else
}
else
{
err2
=
-
EIO
;
if
(
!
rl
)
up_read
(
&
ni
->
runlist
.
lock
);
}
/* Hard error. Abort writing this record. */
if
(
!
err
||
err
==
-
ENOMEM
)
err
=
err2
;
...
...
@@ -949,7 +981,8 @@ static int ntfs_write_mst_block(struct page *page,
"attribute type 0x%x) because "
"its location on disk could "
"not be determined (error "
"code %lli)."
,
(
s64
)
block
<<
"code %lli)."
,
(
long
long
)
block
<<
bh_size_bits
>>
vol
->
mft_record_size_bits
,
ni
->
mft_no
,
ni
->
type
,
...
...
@@ -1223,19 +1256,17 @@ static int ntfs_write_mst_block(struct page *page,
static
int
ntfs_writepage
(
struct
page
*
page
,
struct
writeback_control
*
wbc
)
{
loff_t
i_size
;
struct
inode
*
vi
;
ntfs_inode
*
ni
,
*
base_ni
;
struct
inode
*
vi
=
page
->
mapping
->
host
;
ntfs_inode
*
base_ni
=
NULL
,
*
ni
=
NTFS_I
(
vi
)
;
char
*
kaddr
;
ntfs_attr_search_ctx
*
ctx
;
MFT_RECORD
*
m
;
ntfs_attr_search_ctx
*
ctx
=
NULL
;
MFT_RECORD
*
m
=
NULL
;
u32
attr_len
;
int
err
;
retry_writepage:
BUG_ON
(
!
PageLocked
(
page
));
vi
=
page
->
mapping
->
host
;
i_size
=
i_size_read
(
vi
);
/* Is the page fully outside i_size? (truncate in progress) */
if
(
unlikely
(
page
->
index
>=
(
i_size
+
PAGE_CACHE_SIZE
-
1
)
>>
PAGE_CACHE_SHIFT
))
{
...
...
@@ -1248,8 +1279,6 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
ntfs_debug
(
"Write outside i_size - truncated?"
);
return
0
;
}
ni
=
NTFS_I
(
vi
);
/* NInoNonResident() == NInoIndexAllocPresent() */
if
(
NInoNonResident
(
ni
))
{
/*
...
...
@@ -1326,6 +1355,14 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
ctx
=
NULL
;
goto
err_out
;
}
/*
* If a parallel write made the attribute non-resident, drop the mft
* record and retry the writepage.
*/
if
(
unlikely
(
NInoNonResident
(
ni
)))
{
unmap_mft_record
(
base_ni
);
goto
retry_writepage
;
}
ctx
=
ntfs_attr_get_search_ctx
(
base_ni
,
m
);
if
(
unlikely
(
!
ctx
))
{
err
=
-
ENOMEM
;
...
...
@@ -1367,15 +1404,12 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
*/
attr_len
=
le32_to_cpu
(
ctx
->
attr
->
data
.
resident
.
value_length
);
i_size
=
i_size_read
(
VFS_I
(
ni
));
kaddr
=
kmap_atomic
(
page
,
KM_USER0
);
i_size
=
i_size_read
(
vi
);
if
(
unlikely
(
attr_len
>
i_size
))
{
/* Zero out of bounds area in the mft record. */
memset
((
u8
*
)
ctx
->
attr
+
le16_to_cpu
(
ctx
->
attr
->
data
.
resident
.
value_offset
)
+
i_size
,
0
,
attr_len
-
i_size
);
attr_len
=
i_size
;
ctx
->
attr
->
data
.
resident
.
value_length
=
cpu_to_le32
(
attr_len
);
}
kaddr
=
kmap_atomic
(
page
,
KM_USER0
);
/* Copy the data from the page to the mft record. */
memcpy
((
u8
*
)
ctx
->
attr
+
le16_to_cpu
(
ctx
->
attr
->
data
.
resident
.
value_offset
),
...
...
@@ -1405,8 +1439,10 @@ static int ntfs_writepage(struct page *page, struct writeback_control *wbc)
err
=
0
;
}
else
{
ntfs_error
(
vi
->
i_sb
,
"Resident attribute write failed with "
"error %i.
Setting page error flag.
"
,
err
);
"error %i."
,
err
);
SetPageError
(
page
);
NVolSetErrors
(
ni
->
vol
);
make_bad_inode
(
vi
);
}
unlock_page
(
page
);
if
(
ctx
)
...
...
@@ -1425,12 +1461,15 @@ static int ntfs_prepare_nonresident_write(struct page *page,
{
VCN
vcn
;
LCN
lcn
;
s64
initialized_size
;
loff_t
i_size
;
sector_t
block
,
ablock
,
iblock
;
struct
inode
*
vi
;
ntfs_inode
*
ni
;
ntfs_volume
*
vol
;
runlist_element
*
rl
;
struct
buffer_head
*
bh
,
*
head
,
*
wait
[
2
],
**
wait_bh
=
wait
;
unsigned
long
flags
;
unsigned
int
vcn_ofs
,
block_start
,
block_end
,
blocksize
;
int
err
;
BOOL
is_retry
;
...
...
@@ -1462,16 +1501,20 @@ static int ntfs_prepare_nonresident_write(struct page *page,
/* The first block in the page. */
block
=
(
s64
)
page
->
index
<<
(
PAGE_CACHE_SHIFT
-
blocksize_bits
);
read_lock_irqsave
(
&
ni
->
size_lock
,
flags
);
/*
* The first out of bounds block for the allocated size. No need to
* The first out of bounds block for the allocated size.
No need to
* round up as allocated_size is in multiples of cluster size and the
* minimum cluster size is 512 bytes, which is equal to the smallest
* blocksize.
*/
ablock
=
ni
->
allocated_size
>>
blocksize_bits
;
i_size
=
i_size_read
(
vi
);
initialized_size
=
ni
->
initialized_size
;
read_unlock_irqrestore
(
&
ni
->
size_lock
,
flags
);
/* The last (fully or partially) initialized block. */
iblock
=
ni
->
initialized_size
>>
blocksize_bits
;
iblock
=
initialized_size
>>
blocksize_bits
;
/* Loop through all the buffers in the page. */
block_start
=
0
;
...
...
@@ -1518,7 +1561,7 @@ static int ntfs_prepare_nonresident_write(struct page *page,
* request, i.e. block < ablock is true.
*/
if
(
unlikely
((
block
>=
iblock
)
&&
(
ni
->
initialized_size
<
vi
->
i_size
)))
{
(
initialized_size
<
i_size
)))
{
/*
* If this page is fully outside initialized size, zero
* out all pages between the current initialized size
...
...
@@ -1622,6 +1665,8 @@ static int ntfs_prepare_nonresident_write(struct page *page,
"not supported yet. "
"Sorry."
);
err
=
-
EOPNOTSUPP
;
if
(
!
rl
)
up_read
(
&
ni
->
runlist
.
lock
);
goto
err_out
;
}
else
if
(
!
is_retry
&&
lcn
==
LCN_RL_NOT_MAPPED
)
{
...
...
@@ -1636,7 +1681,8 @@ static int ntfs_prepare_nonresident_write(struct page *page,
goto
lock_retry_remap
;
rl
=
NULL
;
lcn
=
err
;
}
}
else
if
(
!
rl
)
up_read
(
&
ni
->
runlist
.
lock
);
/*
* Failed to map the buffer, even after
* retrying.
...
...
@@ -1797,6 +1843,7 @@ static int ntfs_prepare_write(struct file *file, struct page *page,
unsigned
from
,
unsigned
to
)
{
s64
new_size
;
loff_t
i_size
;
struct
inode
*
vi
=
page
->
mapping
->
host
;
ntfs_inode
*
base_ni
=
NULL
,
*
ni
=
NTFS_I
(
vi
);
ntfs_volume
*
vol
=
ni
->
vol
;
...
...
@@ -1868,14 +1915,8 @@ static int ntfs_prepare_write(struct file *file, struct page *page,
BUG_ON
(
page_has_buffers
(
page
));
new_size
=
((
s64
)
page
->
index
<<
PAGE_CACHE_SHIFT
)
+
to
;
/* If we do not need to resize the attribute allocation we are done. */
if
(
new_size
<=
vi
->
i_size
)
if
(
new_size
<=
i_size_read
(
vi
)
)
goto
done
;
// FIXME: We abort for now as this code is not safe.
ntfs_error
(
vi
->
i_sb
,
"Changing the file size is not supported yet. "
"Sorry."
);
return
-
EOPNOTSUPP
;
/* Map, pin, and lock the (base) mft record. */
if
(
!
NInoAttr
(
ni
))
base_ni
=
ni
;
...
...
@@ -1904,7 +1945,15 @@ static int ntfs_prepare_write(struct file *file, struct page *page,
a
=
ctx
->
attr
;
/* The total length of the attribute value. */
attr_len
=
le32_to_cpu
(
a
->
data
.
resident
.
value_length
);
BUG_ON
(
vi
->
i_size
!=
attr_len
);
/* Fix an eventual previous failure of ntfs_commit_write(). */
i_size
=
i_size_read
(
vi
);
if
(
unlikely
(
attr_len
>
i_size
))
{
attr_len
=
i_size
;
a
->
data
.
resident
.
value_length
=
cpu_to_le32
(
attr_len
);
}
/* If we do not need to resize the attribute allocation we are done. */
if
(
new_size
<=
attr_len
)
goto
done_unm
;
/* Check if new size is allowed in $AttrDef. */
err
=
ntfs_attr_size_bounds_check
(
vol
,
ni
->
type
,
new_size
);
if
(
unlikely
(
err
))
{
...
...
@@ -1962,6 +2011,7 @@ static int ntfs_prepare_write(struct file *file, struct page *page,
}
flush_dcache_mft_record_page
(
ctx
->
ntfs_ino
);
mark_mft_record_dirty
(
ctx
->
ntfs_ino
);
done_unm:
ntfs_attr_put_search_ctx
(
ctx
);
unmap_mft_record
(
base_ni
);
/*
...
...
@@ -2047,7 +2097,7 @@ static int ntfs_commit_nonresident_write(struct page *page,
* now we know ntfs_prepare_write() would have failed in the write
* exceeds i_size case, so this will never trigger which is fine.
*/
if
(
pos
>
vi
->
i_size
)
{
if
(
pos
>
i_size_read
(
vi
)
)
{
ntfs_error
(
vi
->
i_sb
,
"Writing beyond the existing file size is "
"not supported yet. Sorry."
);
return
-
EOPNOTSUPP
;
...
...
@@ -2183,9 +2233,13 @@ static int ntfs_commit_write(struct file *file, struct page *page,
}
kunmap_atomic
(
kaddr
,
KM_USER0
);
/* Update i_size if necessary. */
if
(
vi
->
i_size
<
attr_len
)
{
if
(
i_size_read
(
vi
)
<
attr_len
)
{
unsigned
long
flags
;
write_lock_irqsave
(
&
ni
->
size_lock
,
flags
);
ni
->
allocated_size
=
ni
->
initialized_size
=
attr_len
;
i_size_write
(
vi
,
attr_len
);
write_unlock_irqrestore
(
&
ni
->
size_lock
,
flags
);
}
/* Mark the mft record dirty, so it gets written back. */
flush_dcache_mft_record_page
(
ctx
->
ntfs_ino
);
...
...
fs/ntfs/attrib.c
浏览文件 @
076fb01e
此差异已折叠。
点击以展开。
fs/ntfs/attrib.h
浏览文件 @
076fb01e
...
...
@@ -2,7 +2,7 @@
* attrib.h - Defines for attribute handling in NTFS Linux kernel driver.
* Part of the Linux-NTFS project.
*
* Copyright (c) 2001-200
4
Anton Altaparmakov
* Copyright (c) 2001-200
5
Anton Altaparmakov
* Copyright (c) 2002 Richard Russon
*
* This program/include file is free software; you can redistribute it and/or
...
...
@@ -60,10 +60,14 @@ typedef struct {
ATTR_RECORD
*
base_attr
;
}
ntfs_attr_search_ctx
;
extern
int
ntfs_map_runlist_nolock
(
ntfs_inode
*
ni
,
VCN
vcn
);
extern
int
ntfs_map_runlist
(
ntfs_inode
*
ni
,
VCN
vcn
);
extern
runlist_element
*
ntfs_find_vcn
(
ntfs_inode
*
ni
,
const
VCN
vcn
,
const
BOOL
need_write
);
extern
LCN
ntfs_attr_vcn_to_lcn_nolock
(
ntfs_inode
*
ni
,
const
VCN
vcn
,
const
BOOL
write_locked
);
extern
runlist_element
*
ntfs_attr_find_vcn_nolock
(
ntfs_inode
*
ni
,
const
VCN
vcn
,
const
BOOL
write_locked
);
int
ntfs_attr_lookup
(
const
ATTR_TYPE
type
,
const
ntfschar
*
name
,
const
u32
name_len
,
const
IGNORE_CASE_BOOL
ic
,
...
...
@@ -85,6 +89,8 @@ extern ntfs_attr_search_ctx *ntfs_attr_get_search_ctx(ntfs_inode *ni,
MFT_RECORD
*
mrec
);
extern
void
ntfs_attr_put_search_ctx
(
ntfs_attr_search_ctx
*
ctx
);
#ifdef NTFS_RW
extern
int
ntfs_attr_size_bounds_check
(
const
ntfs_volume
*
vol
,
const
ATTR_TYPE
type
,
const
s64
size
);
extern
int
ntfs_attr_can_be_non_resident
(
const
ntfs_volume
*
vol
,
...
...
@@ -94,7 +100,11 @@ extern int ntfs_attr_can_be_resident(const ntfs_volume *vol,
extern
int
ntfs_attr_record_resize
(
MFT_RECORD
*
m
,
ATTR_RECORD
*
a
,
u32
new_size
);
extern
int
ntfs_attr_make_non_resident
(
ntfs_inode
*
ni
);
extern
int
ntfs_attr_set
(
ntfs_inode
*
ni
,
const
s64
ofs
,
const
s64
cnt
,
const
u8
val
);
#endif
/* NTFS_RW */
#endif
/* _LINUX_NTFS_ATTRIB_H */
fs/ntfs/compress.c
浏览文件 @
076fb01e
...
...
@@ -96,13 +96,14 @@ void free_compression_buffers(void)
/**
* zero_partial_compressed_page - zero out of bounds compressed page region
*/
static
void
zero_partial_compressed_page
(
ntfs_inode
*
ni
,
struct
page
*
page
)
static
void
zero_partial_compressed_page
(
struct
page
*
page
,
const
s64
initialized_size
)
{
u8
*
kp
=
page_address
(
page
);
unsigned
int
kp_ofs
;
ntfs_debug
(
"Zeroing page region outside initialized size."
);
if
(((
s64
)
page
->
index
<<
PAGE_CACHE_SHIFT
)
>=
ni
->
initialized_size
)
{
if
(((
s64
)
page
->
index
<<
PAGE_CACHE_SHIFT
)
>=
initialized_size
)
{
/*
* FIXME: Using clear_page() will become wrong when we get
* PAGE_CACHE_SIZE != PAGE_SIZE but for now there is no problem.
...
...
@@ -110,7 +111,7 @@ static void zero_partial_compressed_page(ntfs_inode *ni, struct page *page)
clear_page
(
kp
);
return
;
}
kp_ofs
=
ni
->
initialized_size
&
~
PAGE_CACHE_MASK
;
kp_ofs
=
initialized_size
&
~
PAGE_CACHE_MASK
;
memset
(
kp
+
kp_ofs
,
0
,
PAGE_CACHE_SIZE
-
kp_ofs
);
return
;
}
...
...
@@ -118,12 +119,12 @@ static void zero_partial_compressed_page(ntfs_inode *ni, struct page *page)
/**
* handle_bounds_compressed_page - test for&handle out of bounds compressed page
*/
static
inline
void
handle_bounds_compressed_page
(
ntfs_inode
*
ni
,
struct
page
*
pag
e
)
static
inline
void
handle_bounds_compressed_page
(
struct
page
*
page
,
const
loff_t
i_size
,
const
s64
initialized_siz
e
)
{
if
((
page
->
index
>=
(
ni
->
initialized_size
>>
PAGE_CACHE_SHIFT
))
&&
(
ni
->
initialized_size
<
VFS_I
(
ni
)
->
i_size
))
zero_partial_compressed_page
(
ni
,
pag
e
);
if
((
page
->
index
>=
(
initialized_size
>>
PAGE_CACHE_SHIFT
))
&&
(
initialized_size
<
i_size
))
zero_partial_compressed_page
(
page
,
initialized_siz
e
);
return
;
}
...
...
@@ -138,6 +139,8 @@ static inline void handle_bounds_compressed_page(ntfs_inode *ni,
* @xpage_done: set to 1 if xpage was completed successfully (IN/OUT)
* @cb_start: compression block to decompress (IN)
* @cb_size: size of compression block @cb_start in bytes (IN)
* @i_size: file size when we started the read (IN)
* @initialized_size: initialized file size when we started the read (IN)
*
* The caller must have disabled preemption. ntfs_decompress() reenables it when
* the critical section is finished.
...
...
@@ -165,7 +168,8 @@ static inline void handle_bounds_compressed_page(ntfs_inode *ni,
static
int
ntfs_decompress
(
struct
page
*
dest_pages
[],
int
*
dest_index
,
int
*
dest_ofs
,
const
int
dest_max_index
,
const
int
dest_max_ofs
,
const
int
xpage
,
char
*
xpage_done
,
u8
*
const
cb_start
,
const
u32
cb_size
)
const
u32
cb_size
,
const
loff_t
i_size
,
const
s64
initialized_size
)
{
/*
* Pointers into the compressed data, i.e. the compression block (cb),
...
...
@@ -219,9 +223,6 @@ static int ntfs_decompress(struct page *dest_pages[], int *dest_index,
spin_unlock
(
&
ntfs_cb_lock
);
/* Second stage: finalize completed pages. */
if
(
nr_completed_pages
>
0
)
{
struct
page
*
page
=
dest_pages
[
completed_pages
[
0
]];
ntfs_inode
*
ni
=
NTFS_I
(
page
->
mapping
->
host
);
for
(
i
=
0
;
i
<
nr_completed_pages
;
i
++
)
{
int
di
=
completed_pages
[
i
];
...
...
@@ -230,7 +231,8 @@ static int ntfs_decompress(struct page *dest_pages[], int *dest_index,
* If we are outside the initialized size, zero
* the out of bounds page range.
*/
handle_bounds_compressed_page
(
ni
,
dp
);
handle_bounds_compressed_page
(
dp
,
i_size
,
initialized_size
);
flush_dcache_page
(
dp
);
kunmap
(
dp
);
SetPageUptodate
(
dp
);
...
...
@@ -478,12 +480,14 @@ static int ntfs_decompress(struct page *dest_pages[], int *dest_index,
*/
int
ntfs_read_compressed_block
(
struct
page
*
page
)
{
loff_t
i_size
;
s64
initialized_size
;
struct
address_space
*
mapping
=
page
->
mapping
;
ntfs_inode
*
ni
=
NTFS_I
(
mapping
->
host
);
ntfs_volume
*
vol
=
ni
->
vol
;
struct
super_block
*
sb
=
vol
->
sb
;
runlist_element
*
rl
;
unsigned
long
block_size
=
sb
->
s_blocksize
;
unsigned
long
flags
,
block_size
=
sb
->
s_blocksize
;
unsigned
char
block_size_bits
=
sb
->
s_blocksize_bits
;
u8
*
cb
,
*
cb_pos
,
*
cb_end
;
struct
buffer_head
**
bhs
;
...
...
@@ -552,8 +556,12 @@ int ntfs_read_compressed_block(struct page *page)
* The remaining pages need to be allocated and inserted into the page
* cache, alignment guarantees keep all the below much simpler. (-8
*/
max_page
=
((
VFS_I
(
ni
)
->
i_size
+
PAGE_CACHE_SIZE
-
1
)
>>
PAGE_CACHE_SHIFT
)
-
offset
;
read_lock_irqsave
(
&
ni
->
size_lock
,
flags
);
i_size
=
i_size_read
(
VFS_I
(
ni
));
initialized_size
=
ni
->
initialized_size
;
read_unlock_irqrestore
(
&
ni
->
size_lock
,
flags
);
max_page
=
((
i_size
+
PAGE_CACHE_SIZE
-
1
)
>>
PAGE_CACHE_SHIFT
)
-
offset
;
if
(
nr_pages
<
max_page
)
max_page
=
nr_pages
;
for
(
i
=
0
;
i
<
max_page
;
i
++
,
offset
++
)
{
...
...
@@ -824,7 +832,8 @@ int ntfs_read_compressed_block(struct page *page)
* If we are outside the initialized size, zero
* the out of bounds page range.
*/
handle_bounds_compressed_page
(
ni
,
page
);
handle_bounds_compressed_page
(
page
,
i_size
,
initialized_size
);
flush_dcache_page
(
page
);
kunmap
(
page
);
SetPageUptodate
(
page
);
...
...
@@ -847,7 +856,8 @@ int ntfs_read_compressed_block(struct page *page)
ntfs_debug
(
"Found compressed compression block."
);
err
=
ntfs_decompress
(
pages
,
&
cur_page
,
&
cur_ofs
,
cb_max_page
,
cb_max_ofs
,
xpage
,
&
xpage_done
,
cb_pos
,
cb_size
-
(
cb_pos
-
cb
));
cb_pos
,
cb_size
-
(
cb_pos
-
cb
),
i_size
,
initialized_size
);
/*
* We can sleep from now on, lock already dropped by
* ntfs_decompress().
...
...
fs/ntfs/debug.c
浏览文件 @
076fb01e
...
...
@@ -164,14 +164,17 @@ void ntfs_debug_dump_runlist(const runlist_element *rl)
if
(
index
>
-
LCN_ENOENT
-
1
)
index
=
3
;
printk
(
KERN_DEBUG
"%-16Lx %s %-16Lx%s
\n
"
,
(
rl
+
i
)
->
vcn
,
lcn_str
[
index
],
(
rl
+
i
)
->
length
,
(
rl
+
i
)
->
length
?
""
:
" (runlist end)"
);
(
long
long
)(
rl
+
i
)
->
vcn
,
lcn_str
[
index
],
(
long
long
)(
rl
+
i
)
->
length
,
(
rl
+
i
)
->
length
?
""
:
" (runlist end)"
);
}
else
printk
(
KERN_DEBUG
"%-16Lx %-16Lx %-16Lx%s
\n
"
,
(
rl
+
i
)
->
vcn
,
(
rl
+
i
)
->
lcn
,
(
rl
+
i
)
->
length
,
(
rl
+
i
)
->
length
?
""
:
" (runlist end)"
);
(
long
long
)(
rl
+
i
)
->
vcn
,
(
long
long
)(
rl
+
i
)
->
lcn
,
(
long
long
)(
rl
+
i
)
->
length
,
(
rl
+
i
)
->
length
?
""
:
" (runlist end)"
);
if
(
!
(
rl
+
i
)
->
length
)
break
;
}
...
...
fs/ntfs/dir.c
浏览文件 @
076fb01e
/**
* dir.c - NTFS kernel directory operations. Part of the Linux-NTFS project.
*
* Copyright (c) 2001-200
4
Anton Altaparmakov
* Copyright (c) 2001-200
5
Anton Altaparmakov
* Copyright (c) 2002 Richard Russon
*
* This program/include file is free software; you can redistribute it and/or
...
...
@@ -183,8 +183,7 @@ MFT_REF ntfs_lookup_inode_by_name(ntfs_inode *dir_ni, const ntfschar *uname,
name
->
len
=
0
;
*
res
=
name
;
}
else
{
if
(
name
)
kfree
(
name
);
kfree
(
name
);
*
res
=
NULL
;
}
mref
=
le64_to_cpu
(
ie
->
data
.
dir
.
indexed_file
);
...
...
@@ -444,8 +443,7 @@ MFT_REF ntfs_lookup_inode_by_name(ntfs_inode *dir_ni, const ntfschar *uname,
name
->
len
=
0
;
*
res
=
name
;
}
else
{
if
(
name
)
kfree
(
name
);
kfree
(
name
);
*
res
=
NULL
;
}
mref
=
le64_to_cpu
(
ie
->
data
.
dir
.
indexed_file
);
...
...
@@ -610,7 +608,7 @@ MFT_REF ntfs_lookup_inode_by_name(ntfs_inode *dir_ni, const ntfschar *uname,
// TODO: (AIA)
// The algorithm embedded in this code will be required for the time when we
// want to support adding of entries to directories, where we require correct
// collation of file names in order not to cause corruption of the file
system.
// collation of file names in order not to cause corruption of the filesystem.
/**
* ntfs_lookup_inode_by_name - find an inode in a directory given its name
...
...
@@ -1101,7 +1099,7 @@ static inline int ntfs_filldir(ntfs_volume *vol, loff_t fpos,
static
int
ntfs_readdir
(
struct
file
*
filp
,
void
*
dirent
,
filldir_t
filldir
)
{
s64
ia_pos
,
ia_start
,
prev_ia_pos
,
bmp_pos
;
loff_t
fpos
;
loff_t
fpos
,
i_size
;
struct
inode
*
bmp_vi
,
*
vdir
=
filp
->
f_dentry
->
d_inode
;
struct
super_block
*
sb
=
vdir
->
i_sb
;
ntfs_inode
*
ndir
=
NTFS_I
(
vdir
);
...
...
@@ -1122,7 +1120,8 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
vdir
->
i_ino
,
fpos
);
rc
=
err
=
0
;
/* Are we at end of dir yet? */
if
(
fpos
>=
vdir
->
i_size
+
vol
->
mft_record_size
)
i_size
=
i_size_read
(
vdir
);
if
(
fpos
>=
i_size
+
vol
->
mft_record_size
)
goto
done
;
/* Emulate . and .. for all directories. */
if
(
!
fpos
)
{
...
...
@@ -1264,7 +1263,7 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
bmp_mapping
=
bmp_vi
->
i_mapping
;
/* Get the starting bitmap bit position and sanity check it. */
bmp_pos
=
ia_pos
>>
ndir
->
itype
.
index
.
block_size_bits
;
if
(
unlikely
(
bmp_pos
>>
3
>=
bmp_vi
->
i_size
))
{
if
(
unlikely
(
bmp_pos
>>
3
>=
i_size_read
(
bmp_vi
)
))
{
ntfs_error
(
sb
,
"Current index allocation position exceeds "
"index bitmap size."
);
goto
err_out
;
...
...
@@ -1301,7 +1300,7 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
goto
get_next_bmp_page
;
}
/* If we have reached the end of the bitmap, we are done. */
if
(
unlikely
(((
bmp_pos
+
cur_bmp_pos
)
>>
3
)
>=
vdir
->
i_size
))
if
(
unlikely
(((
bmp_pos
+
cur_bmp_pos
)
>>
3
)
>=
i_size
))
goto
unm_EOD
;
ia_pos
=
(
bmp_pos
+
cur_bmp_pos
)
<<
ndir
->
itype
.
index
.
block_size_bits
;
...
...
@@ -1309,7 +1308,8 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
ntfs_debug
(
"Handling index buffer 0x%llx."
,
(
unsigned
long
long
)
bmp_pos
+
cur_bmp_pos
);
/* If the current index buffer is in the same page we reuse the page. */
if
((
prev_ia_pos
&
PAGE_CACHE_MASK
)
!=
(
ia_pos
&
PAGE_CACHE_MASK
))
{
if
((
prev_ia_pos
&
(
s64
)
PAGE_CACHE_MASK
)
!=
(
ia_pos
&
(
s64
)
PAGE_CACHE_MASK
))
{
prev_ia_pos
=
ia_pos
;
if
(
likely
(
ia_page
!=
NULL
))
{
unlock_page
(
ia_page
);
...
...
@@ -1441,7 +1441,7 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
ntfs_unmap_page
(
bmp_page
);
EOD:
/* We are finished, set fpos to EOD. */
fpos
=
vdir
->
i_size
+
vol
->
mft_record_size
;
fpos
=
i_size
+
vol
->
mft_record_size
;
abort:
kfree
(
name
);
done:
...
...
@@ -1461,10 +1461,8 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
unlock_page
(
ia_page
);
ntfs_unmap_page
(
ia_page
);
}
if
(
ir
)
kfree
(
ir
);
if
(
name
)
kfree
(
name
);
kfree
(
ir
);
kfree
(
name
);
if
(
ctx
)
ntfs_attr_put_search_ctx
(
ctx
);
if
(
m
)
...
...
@@ -1495,7 +1493,7 @@ static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
static
int
ntfs_dir_open
(
struct
inode
*
vi
,
struct
file
*
filp
)
{
if
(
sizeof
(
unsigned
long
)
<
8
)
{
if
(
vi
->
i_size
>
MAX_LFS_FILESIZE
)
if
(
i_size_read
(
vi
)
>
MAX_LFS_FILESIZE
)
return
-
EFBIG
;
}
return
0
;
...
...
fs/ntfs/file.c
浏览文件 @
076fb01e
...
...
@@ -47,7 +47,7 @@
static
int
ntfs_file_open
(
struct
inode
*
vi
,
struct
file
*
filp
)
{
if
(
sizeof
(
unsigned
long
)
<
8
)
{
if
(
vi
->
i_size
>
MAX_LFS_FILESIZE
)
if
(
i_size_read
(
vi
)
>
MAX_LFS_FILESIZE
)
return
-
EFBIG
;
}
return
generic_file_open
(
vi
,
filp
);
...
...
fs/ntfs/index.c
浏览文件 @
076fb01e
/*
* index.c - NTFS kernel index handling. Part of the Linux-NTFS project.
*
* Copyright (c) 2004 Anton Altaparmakov
* Copyright (c) 2004
-2005
Anton Altaparmakov
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
...
...
@@ -39,18 +39,8 @@ ntfs_index_context *ntfs_index_ctx_get(ntfs_inode *idx_ni)
ntfs_index_context
*
ictx
;
ictx
=
kmem_cache_alloc
(
ntfs_index_ctx_cache
,
SLAB_NOFS
);
if
(
ictx
)
{
ictx
->
idx_ni
=
idx_ni
;
ictx
->
entry
=
NULL
;
ictx
->
data
=
NULL
;
ictx
->
data_len
=
0
;
ictx
->
is_in_root
=
0
;
ictx
->
ir
=
NULL
;
ictx
->
actx
=
NULL
;
ictx
->
base_ni
=
NULL
;
ictx
->
ia
=
NULL
;
ictx
->
page
=
NULL
;
}
if
(
ictx
)
*
ictx
=
(
ntfs_index_context
){
.
idx_ni
=
idx_ni
};
return
ictx
;
}
...
...
fs/ntfs/inode.c
浏览文件 @
076fb01e
此差异已折叠。
点击以展开。
fs/ntfs/inode.h
浏览文件 @
076fb01e
...
...
@@ -2,7 +2,7 @@
* inode.h - Defines for inode structures NTFS Linux kernel driver. Part of
* the Linux-NTFS project.
*
* Copyright (c) 2001-200
4
Anton Altaparmakov
* Copyright (c) 2001-200
5
Anton Altaparmakov
* Copyright (c) 2002 Richard Russon
*
* This program/include file is free software; you can redistribute it and/or
...
...
@@ -44,6 +44,7 @@ typedef struct _ntfs_inode ntfs_inode;
* fields already provided in the VFS inode.
*/
struct
_ntfs_inode
{
rwlock_t
size_lock
;
/* Lock serializing access to inode sizes. */
s64
initialized_size
;
/* Copy from the attribute record. */
s64
allocated_size
;
/* Copy from the attribute record. */
unsigned
long
state
;
/* NTFS specific flags describing this inode.
...
...
@@ -109,7 +110,7 @@ struct _ntfs_inode {
u8
block_size_bits
;
/* Log2 of the above. */
u8
vcn_size_bits
;
/* Log2 of the above. */
}
index
;
struct
{
/* It is a compressed
file or an
attribute inode. */
struct
{
/* It is a compressed
/sparse file/
attribute inode. */
s64
size
;
/* Copy of compressed_size from
$DATA. */
u32
block_size
;
/* Size of a compression block
...
...
@@ -165,6 +166,7 @@ typedef enum {
NI_Sparse
,
/* 1: Unnamed data attr is sparse (f).
1: Create sparse files by default (d).
1: Attribute is sparse (a). */
NI_SparseDisabled
,
/* 1: May not create sparse regions. */
NI_TruncateFailed
,
/* 1: Last ntfs_truncate() call failed. */
}
ntfs_inode_state_bits
;
...
...
@@ -217,6 +219,7 @@ NINO_FNS(IndexAllocPresent)
NINO_FNS
(
Compressed
)
NINO_FNS
(
Encrypted
)
NINO_FNS
(
Sparse
)
NINO_FNS
(
SparseDisabled
)
NINO_FNS
(
TruncateFailed
)
/*
...
...
fs/ntfs/layout.h
浏览文件 @
076fb01e
...
...
@@ -2,7 +2,7 @@
* layout.h - All NTFS associated on-disk structures. Part of the Linux-NTFS
* project.
*
* Copyright (c) 2001-200
4
Anton Altaparmakov
* Copyright (c) 2001-200
5
Anton Altaparmakov
* Copyright (c) 2002 Richard Russon
*
* This program/include file is free software; you can redistribute it and/or
...
...
@@ -547,26 +547,44 @@ enum {
COLLATION_NTOFS_ULONG
=
const_cpu_to_le32
(
0x10
),
COLLATION_NTOFS_SID
=
const_cpu_to_le32
(
0x11
),
COLLATION_NTOFS_SECURITY_HASH
=
const_cpu_to_le32
(
0x12
),
COLLATION_NTOFS_ULONGS
=
const_cpu_to_le32
(
0x13
)
COLLATION_NTOFS_ULONGS
=
const_cpu_to_le32
(
0x13
)
,
};
typedef
le32
COLLATION_RULE
;
/*
* The flags (32-bit) describing attribute properties in the attribute
* definition structure. FIXME: This information is from Regis's information
* and, according to him, it is not certain and probably incomplete.
* The INDEXABLE flag is fairly certainly correct as only the file name
* attribute has this flag set and this is the only attribute indexed in NT4.
* definition structure. FIXME: This information is based on Regis's
* information and, according to him, it is not certain and probably
* incomplete. The INDEXABLE flag is fairly certainly correct as only the file
* name attribute has this flag set and this is the only attribute indexed in
* NT4.
*/
enum
{
INDEXABLE
=
const_cpu_to_le32
(
0x02
),
/* Attribute can be
indexed. */
NEED_TO_REGENERATE
=
const_cpu_to_le32
(
0x40
),
/* Need to regenerate
during regeneration
phase. */
CAN_BE_NON_RESIDENT
=
const_cpu_to_le32
(
0x80
),
/* Attribute can be
non-resident. */
ATTR_DEF_INDEXABLE
=
const_cpu_to_le32
(
0x02
),
/* Attribute can be
indexed. */
ATTR_DEF_MULTIPLE
=
const_cpu_to_le32
(
0x04
),
/* Attribute type
can be present multiple times in the
mft records of an inode. */
ATTR_DEF_NOT_ZERO
=
const_cpu_to_le32
(
0x08
),
/* Attribute value
must contain at least one non-zero
byte. */
ATTR_DEF_INDEXED_UNIQUE
=
const_cpu_to_le32
(
0x10
),
/* Attribute must be
indexed and the attribute value must be
unique for the attribute type in all of
the mft records of an inode. */
ATTR_DEF_NAMED_UNIQUE
=
const_cpu_to_le32
(
0x20
),
/* Attribute must be
named and the name must be unique for
the attribute type in all of the mft
records of an inode. */
ATTR_DEF_RESIDENT
=
const_cpu_to_le32
(
0x40
),
/* Attribute must be
resident. */
ATTR_DEF_ALWAYS_LOG
=
const_cpu_to_le32
(
0x80
),
/* Always log
modifications to this attribute,
regardless of whether it is resident or
non-resident. Without this, only log
modifications if the attribute is
resident. */
};
typedef
le32
ATTR_DEF_FLAGS
;
...
...
@@ -749,10 +767,11 @@ typedef struct {
record header aligned to 8-byte boundary. */
/* 34*/
u8
compression_unit
;
/* The compression unit expressed
as the log to the base 2 of the number of
clusters in a compression unit. 0 means not
compressed. (This effectively limits the
clusters in a compression unit.
0 means not
compressed.
(This effectively limits the
compression unit size to be a power of two
clusters.) WinNT4 only uses a value of 4. */
clusters.) WinNT4 only uses a value of 4.
Sparse files also have this set to 4. */
/* 35*/
u8
reserved
[
5
];
/* Align to 8-byte boundary. */
/* The sizes below are only used when lowest_vcn is zero, as otherwise it would
be difficult to keep them up-to-date.*/
...
...
@@ -772,10 +791,10 @@ typedef struct {
data_size. */
/* sizeof(uncompressed attr) = 64*/
/* 64*/
sle64
compressed_size
;
/* Byte size of the attribute
value after compression. Only present when
compressed
. Always is a multiple of the
cluster size. Represents the actual amount of
disk space being used on the disk. */
value after compression.
Only present when
compressed
or sparse. Always is a multiple of
the cluster size. Represents the actual amount
of
disk space being used on the disk. */
/* sizeof(compressed attr) = 72*/
}
__attribute__
((
__packed__
))
non_resident
;
}
__attribute__
((
__packed__
))
data
;
...
...
@@ -834,7 +853,7 @@ enum {
/* Note, this is a copy of the corresponding bit from the mft record,
telling us whether this file has a view index present (eg. object id
index, quota index, one of the security indexes or the encrypting
file
system related indexes). */
filesystem related indexes). */
};
typedef
le32
FILE_ATTR_FLAGS
;
...
...
@@ -917,20 +936,12 @@ typedef struct {
/* 56*/
le64
quota_charged
;
/* Byte size of the charge to
the quota for all streams of the file. Note: Is
zero if quotas are disabled. */
/* 64*/
le64
usn
;
/* Last update sequence number
of the file. This is a direct index into the
change (aka usn) journal file. It is zero if
the usn journal is disabled.
NOTE: To disable the journal need to delete
the journal file itself and to then walk the
whole mft and set all Usn entries in all mft
records to zero! (This can take a while!)
The journal is FILE_Extend/$UsnJrnl. Win2k
will recreate the journal and initiate
logging if necessary when mounting the
partition. This, in contrast to disabling the
journal is a very fast process, so the user
won't even notice it. */
/* 64*/
leUSN
usn
;
/* Last update sequence number
of the file. This is a direct index into the
transaction log file ($UsnJrnl). It is zero if
the usn journal is disabled or this file has
not been subject to logging yet. See usnjrnl.h
for details. */
}
__attribute__
((
__packed__
))
v3
;
/* sizeof() = 72 bytes (NTFS 3.x) */
}
__attribute__
((
__packed__
))
ver
;
...
...
@@ -1893,7 +1904,7 @@ enum {
VOLUME_FLAGS_MASK
=
const_cpu_to_le16
(
0x803f
),
/* To make our life easier when checking if we must mount read-only. */
VOLUME_MUST_MOUNT_RO_MASK
=
const_cpu_to_le16
(
0x80
3
7
),
VOLUME_MUST_MOUNT_RO_MASK
=
const_cpu_to_le16
(
0x80
2
7
),
}
__attribute__
((
__packed__
));
typedef
le16
VOLUME_FLAGS
;
...
...
fs/ntfs/lcnalloc.c
浏览文件 @
076fb01e
/*
* lcnalloc.c - Cluster (de)allocation code. Part of the Linux-NTFS project.
*
* Copyright (c) 2004 Anton Altaparmakov
* Copyright (c) 2004
-2005
Anton Altaparmakov
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
...
...
@@ -60,7 +60,7 @@ int ntfs_cluster_free_from_rl_nolock(ntfs_volume *vol,
if
(
rl
->
lcn
<
0
)
continue
;
err
=
ntfs_bitmap_clear_run
(
lcnbmp_vi
,
rl
->
lcn
,
rl
->
length
);
if
(
unlikely
(
err
&&
(
!
ret
||
ret
==
ENOMEM
)
&&
ret
!=
err
))
if
(
unlikely
(
err
&&
(
!
ret
||
ret
==
-
ENOMEM
)
&&
ret
!=
err
))
ret
=
err
;
}
ntfs_debug
(
"Done."
);
...
...
@@ -140,6 +140,7 @@ runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn,
LCN
zone_start
,
zone_end
,
bmp_pos
,
bmp_initial_pos
,
last_read_pos
,
lcn
;
LCN
prev_lcn
=
0
,
prev_run_len
=
0
,
mft_zone_size
;
s64
clusters
;
loff_t
i_size
;
struct
inode
*
lcnbmp_vi
;
runlist_element
*
rl
=
NULL
;
struct
address_space
*
mapping
;
...
...
@@ -249,6 +250,7 @@ runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn,
clusters
=
count
;
rlpos
=
rlsize
=
0
;
mapping
=
lcnbmp_vi
->
i_mapping
;
i_size
=
i_size_read
(
lcnbmp_vi
);
while
(
1
)
{
ntfs_debug
(
"Start of outer while loop: done_zones 0x%x, "
"search_zone %i, pass %i, zone_start 0x%llx, "
...
...
@@ -263,7 +265,7 @@ runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn,
last_read_pos
=
bmp_pos
>>
3
;
ntfs_debug
(
"last_read_pos 0x%llx."
,
(
unsigned
long
long
)
last_read_pos
);
if
(
last_read_pos
>
lcnbmp_vi
->
i_size
)
{
if
(
last_read_pos
>
i_size
)
{
ntfs_debug
(
"End of attribute reached. "
"Skipping to zone_pass_done."
);
goto
zone_pass_done
;
...
...
@@ -287,11 +289,11 @@ runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn,
buf_size
=
last_read_pos
&
~
PAGE_CACHE_MASK
;
buf
=
page_address
(
page
)
+
buf_size
;
buf_size
=
PAGE_CACHE_SIZE
-
buf_size
;
if
(
unlikely
(
last_read_pos
+
buf_size
>
lcnbmp_vi
->
i_size
))
buf_size
=
lcnbmp_vi
->
i_size
-
last_read_pos
;
if
(
unlikely
(
last_read_pos
+
buf_size
>
i_size
))
buf_size
=
i_size
-
last_read_pos
;
buf_size
<<=
3
;
lcn
=
bmp_pos
&
7
;
bmp_pos
&=
~
7
;
bmp_pos
&=
~
(
LCN
)
7
;
ntfs_debug
(
"Before inner while loop: buf_size %i, lcn 0x%llx, "
"bmp_pos 0x%llx, need_writeback %i."
,
buf_size
,
(
unsigned
long
long
)
lcn
,
...
...
@@ -309,7 +311,7 @@ runlist_element *ntfs_cluster_alloc(ntfs_volume *vol, const VCN start_vcn,
(
unsigned
int
)
*
byte
);
/* Skip full bytes. */
if
(
*
byte
==
0xff
)
{
lcn
=
(
lcn
+
8
)
&
~
7
;
lcn
=
(
lcn
+
8
)
&
~
(
LCN
)
7
;
ntfs_debug
(
"Continuing while loop 1."
);
continue
;
}
...
...
@@ -691,7 +693,7 @@ switch_to_data1_zone: search_zone = 2;
if
(
zone
==
MFT_ZONE
||
mft_zone_size
<=
0
)
{
ntfs_debug
(
"No free clusters left, going to out."
);
/* Really no more space left on device. */
err
=
ENOSPC
;
err
=
-
ENOSPC
;
goto
out
;
}
/* zone == DATA_ZONE && mft_zone_size > 0 */
ntfs_debug
(
"Shrinking mft zone."
);
...
...
@@ -755,13 +757,13 @@ switch_to_data1_zone: search_zone = 2;
if
(
rl
)
{
int
err2
;
if
(
err
==
ENOSPC
)
if
(
err
==
-
ENOSPC
)
ntfs_debug
(
"Not enough space to complete allocation, "
"err ENOSPC, first free lcn 0x%llx, "
"err
-
ENOSPC, first free lcn 0x%llx, "
"could allocate up to 0x%llx "
"clusters."
,
(
unsigned
long
long
)
rl
[
0
].
lcn
,
(
unsigned
long
long
)
count
-
clusters
);
(
unsigned
long
long
)
(
count
-
clusters
)
);
/* Deallocate all allocated clusters. */
ntfs_debug
(
"Attempting rollback..."
);
err2
=
ntfs_cluster_free_from_rl_nolock
(
vol
,
rl
);
...
...
@@ -773,10 +775,10 @@ switch_to_data1_zone: search_zone = 2;
}
/* Free the runlist. */
ntfs_free
(
rl
);
}
else
if
(
err
==
ENOSPC
)
ntfs_debug
(
"No space left at all, err =
ENOSPC,
"
"
first free
lcn = 0x%llx."
,
(
unsigned
long
long
)
vol
->
data1_zone_pos
);
}
else
if
(
err
==
-
ENOSPC
)
ntfs_debug
(
"No space left at all, err =
-ENOSPC, first free
"
"lcn = 0x%llx."
,
(
long
long
)
vol
->
data1_zone_pos
);
up_write
(
&
vol
->
lcnbmp_lock
);
return
ERR_PTR
(
err
);
}
...
...
@@ -846,8 +848,8 @@ s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count,
total_freed
=
real_freed
=
0
;
/* This returns with ni->runlist locked for reading on success. */
rl
=
ntfs_
find_vcn
(
ni
,
start_vcn
,
FALSE
);
down_read
(
&
ni
->
runlist
.
lock
);
rl
=
ntfs_
attr_find_vcn_nolock
(
ni
,
start_vcn
,
FALSE
);
if
(
IS_ERR
(
rl
))
{
if
(
!
is_rollback
)
ntfs_error
(
vol
->
sb
,
"Failed to find first runlist "
...
...
@@ -861,7 +863,7 @@ s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count,
ntfs_error
(
vol
->
sb
,
"First runlist element has "
"invalid lcn, aborting."
);
err
=
-
EIO
;
goto
unl_
err_out
;
goto
err_out
;
}
/* Find the starting cluster inside the run that needs freeing. */
delta
=
start_vcn
-
rl
->
vcn
;
...
...
@@ -879,7 +881,7 @@ s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count,
if
(
!
is_rollback
)
ntfs_error
(
vol
->
sb
,
"Failed to clear first run "
"(error %i), aborting."
,
err
);
goto
unl_
err_out
;
goto
err_out
;
}
/* We have freed @to_free real clusters. */
real_freed
=
to_free
;
...
...
@@ -899,30 +901,15 @@ s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count,
if
(
unlikely
(
rl
->
lcn
<
LCN_HOLE
))
{
VCN
vcn
;
/*
* Attempt to map runlist, dropping runlist lock for
* the duration.
*/
/* Attempt to map runlist. */
vcn
=
rl
->
vcn
;
up_read
(
&
ni
->
runlist
.
lock
);
err
=
ntfs_map_runlist
(
ni
,
vcn
);
if
(
err
)
{
if
(
!
is_rollback
)
ntfs_error
(
vol
->
sb
,
"Failed to map "
"runlist fragment."
);
if
(
err
==
-
EINVAL
||
err
==
-
ENOENT
)
err
=
-
EIO
;
goto
err_out
;
}
/*
* This returns with ni->runlist locked for reading on
* success.
*/
rl
=
ntfs_find_vcn
(
ni
,
vcn
,
FALSE
);
rl
=
ntfs_attr_find_vcn_nolock
(
ni
,
vcn
,
FALSE
);
if
(
IS_ERR
(
rl
))
{
err
=
PTR_ERR
(
rl
);
if
(
!
is_rollback
)
ntfs_error
(
vol
->
sb
,
"Failed to find "
ntfs_error
(
vol
->
sb
,
"Failed to map "
"runlist fragment or "
"failed to find "
"subsequent runlist "
"element."
);
goto
err_out
;
...
...
@@ -935,7 +922,7 @@ s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count,
(
unsigned
long
long
)
rl
->
lcn
);
err
=
-
EIO
;
goto
unl_
err_out
;
goto
err_out
;
}
}
/* The number of clusters in this run that need freeing. */
...
...
@@ -951,7 +938,7 @@ s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count,
if
(
!
is_rollback
)
ntfs_error
(
vol
->
sb
,
"Failed to clear "
"subsequent run."
);
goto
unl_
err_out
;
goto
err_out
;
}
/* We have freed @to_free real clusters. */
real_freed
+=
to_free
;
...
...
@@ -972,9 +959,8 @@ s64 __ntfs_cluster_free(struct inode *vi, const VCN start_vcn, s64 count,
/* We are done. Return the number of actually freed clusters. */
ntfs_debug
(
"Done."
);
return
real_freed
;
unl_err_out:
up_read
(
&
ni
->
runlist
.
lock
);
err_out:
up_read
(
&
ni
->
runlist
.
lock
);
if
(
is_rollback
)
return
err
;
/* If no real clusters were freed, no need to rollback. */
...
...
fs/ntfs/logfile.c
浏览文件 @
076fb01e
/*
* logfile.c - NTFS kernel journal handling. Part of the Linux-NTFS project.
*
* Copyright (c) 2002-200
4
Anton Altaparmakov
* Copyright (c) 2002-200
5
Anton Altaparmakov
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
...
...
@@ -410,7 +410,7 @@ static BOOL ntfs_check_and_load_restart_page(struct inode *vi,
}
/**
* ntfs_c
keck_logfile - check in the journal if the volume is consistent
* ntfs_c
heck_logfile - check the journal for consistency
* @log_vi: struct inode of loaded journal $LogFile to check
*
* Check the $LogFile journal for consistency and return TRUE if it is
...
...
@@ -443,7 +443,7 @@ BOOL ntfs_check_logfile(struct inode *log_vi)
/* An empty $LogFile must have been clean before it got emptied. */
if
(
NVolLogFileEmpty
(
vol
))
goto
is_empty
;
size
=
log_vi
->
i_size
;
size
=
i_size_read
(
log_vi
)
;
/* Make sure the file doesn't exceed the maximum allowed size. */
if
(
size
>
MaxLogFileSize
)
size
=
MaxLogFileSize
;
...
...
@@ -464,7 +464,7 @@ BOOL ntfs_check_logfile(struct inode *log_vi)
* optimize log_page_size and log_page_bits into constants.
*/
log_page_bits
=
generic_ffs
(
log_page_size
)
-
1
;
size
&=
~
(
log_page_size
-
1
);
size
&=
~
(
s64
)(
log_page_size
-
1
);
/*
* Ensure the log file is big enough to store at least the two restart
* pages and the minimum number of log record pages.
...
...
@@ -689,7 +689,8 @@ BOOL ntfs_empty_logfile(struct inode *log_vi)
if
(
!
NVolLogFileEmpty
(
vol
))
{
int
err
;
err
=
ntfs_attr_set
(
NTFS_I
(
log_vi
),
0
,
log_vi
->
i_size
,
0xff
);
err
=
ntfs_attr_set
(
NTFS_I
(
log_vi
),
0
,
i_size_read
(
log_vi
),
0xff
);
if
(
unlikely
(
err
))
{
ntfs_error
(
vol
->
sb
,
"Failed to fill $LogFile with "
"0xff bytes (error code %i)."
,
err
);
...
...
fs/ntfs/mft.c
浏览文件 @
076fb01e
此差异已折叠。
点击以展开。
fs/ntfs/namei.c
浏览文件 @
076fb01e
...
...
@@ -153,8 +153,7 @@ static struct dentry *ntfs_lookup(struct inode *dir_ino, struct dentry *dent,
ntfs_error
(
vol
->
sb
,
"ntfs_iget(0x%lx) failed with "
"error code %li."
,
dent_ino
,
PTR_ERR
(
dent_inode
));
if
(
name
)
kfree
(
name
);
kfree
(
name
);
/* Return the error code. */
return
(
struct
dentry
*
)
dent_inode
;
}
...
...
@@ -380,7 +379,7 @@ struct inode_operations ntfs_dir_inode_ops = {
* Return the dentry of the parent directory on success or the error code on
* error (IS_ERR() is true).
*/
struct
dentry
*
ntfs_get_parent
(
struct
dentry
*
child_dent
)
st
atic
st
ruct
dentry
*
ntfs_get_parent
(
struct
dentry
*
child_dent
)
{
struct
inode
*
vi
=
child_dent
->
d_inode
;
ntfs_inode
*
ni
=
NTFS_I
(
vi
);
...
...
@@ -465,7 +464,7 @@ struct dentry *ntfs_get_parent(struct dentry *child_dent)
*
* Return the dentry on success or the error code on error (IS_ERR() is true).
*/
struct
dentry
*
ntfs_get_dentry
(
struct
super_block
*
sb
,
void
*
fh
)
st
atic
st
ruct
dentry
*
ntfs_get_dentry
(
struct
super_block
*
sb
,
void
*
fh
)
{
struct
inode
*
vi
;
struct
dentry
*
dent
;
...
...
@@ -496,3 +495,30 @@ struct dentry *ntfs_get_dentry(struct super_block *sb, void *fh)
ntfs_debug
(
"Done for inode 0x%lx, generation 0x%x."
,
ino
,
gen
);
return
dent
;
}
/**
* Export operations allowing NFS exporting of mounted NTFS partitions.
*
* We use the default ->decode_fh() and ->encode_fh() for now. Note that they
* use 32 bits to store the inode number which is an unsigned long so on 64-bit
* architectures is usually 64 bits so it would all fail horribly on huge
* volumes. I guess we need to define our own encode and decode fh functions
* that store 64-bit inode numbers at some point but for now we will ignore the
* problem...
*
* We also use the default ->get_name() helper (used by ->decode_fh() via
* fs/exportfs/expfs.c::find_exported_dentry()) as that is completely fs
* independent.
*
* The default ->get_parent() just returns -EACCES so we have to provide our
* own and the default ->get_dentry() is incompatible with NTFS due to not
* allowing the inode number 0 which is used in NTFS for the system file $MFT
* and due to using iget() whereas NTFS needs ntfs_iget().
*/
struct
export_operations
ntfs_export_ops
=
{
.
get_parent
=
ntfs_get_parent
,
/* Find the parent of a given
directory. */
.
get_dentry
=
ntfs_get_dentry
,
/* Find a dentry for the inode
given a file handle
sub-fragment. */
};
fs/ntfs/ntfs.h
浏览文件 @
076fb01e
...
...
@@ -2,7 +2,7 @@
* ntfs.h - Defines for NTFS Linux kernel driver. Part of the Linux-NTFS
* project.
*
* Copyright (c) 2001-200
4
Anton Altaparmakov
* Copyright (c) 2001-200
5
Anton Altaparmakov
* Copyright (C) 2002 Richard Russon
*
* This program/include file is free software; you can redistribute it and/or
...
...
@@ -31,6 +31,7 @@
#include <linux/fs.h>
#include <linux/nls.h>
#include <linux/smp.h>
#include <linux/pagemap.h>
#include "types.h"
#include "volume.h"
...
...
@@ -41,6 +42,9 @@ typedef enum {
NTFS_BLOCK_SIZE_BITS
=
9
,
NTFS_SB_MAGIC
=
0x5346544e
,
/* 'NTFS' */
NTFS_MAX_NAME_LEN
=
255
,
NTFS_MAX_ATTR_NAME_LEN
=
255
,
NTFS_MAX_CLUSTER_SIZE
=
64
*
1024
,
/* 64kiB */
NTFS_MAX_PAGES_PER_CLUSTER
=
NTFS_MAX_CLUSTER_SIZE
/
PAGE_CACHE_SIZE
,
}
NTFS_CONSTANTS
;
/* Global variables. */
...
...
@@ -65,6 +69,8 @@ extern struct inode_operations ntfs_dir_inode_ops;
extern
struct
file_operations
ntfs_empty_file_ops
;
extern
struct
inode_operations
ntfs_empty_inode_ops
;
extern
struct
export_operations
ntfs_export_ops
;
/**
* NTFS_SB - return the ntfs volume given a vfs super block
* @sb: VFS super block
...
...
fs/ntfs/runlist.c
浏览文件 @
076fb01e
此差异已折叠。
点击以展开。
fs/ntfs/runlist.h
浏览文件 @
076fb01e
...
...
@@ -2,7 +2,7 @@
* runlist.h - Defines for runlist handling in NTFS Linux kernel driver.
* Part of the Linux-NTFS project.
*
* Copyright (c) 2001-200
4
Anton Altaparmakov
* Copyright (c) 2001-200
5
Anton Altaparmakov
* Copyright (c) 2002 Richard Russon
*
* This program/include file is free software; you can redistribute it and/or
...
...
@@ -66,6 +66,8 @@ typedef enum {
LCN_HOLE
=
-
1
,
/* Keep this as highest value or die! */
LCN_RL_NOT_MAPPED
=
-
2
,
LCN_ENOENT
=
-
3
,
LCN_ENOMEM
=
-
4
,
LCN_EIO
=
-
5
,
}
LCN_SPECIAL_VALUES
;
extern
runlist_element
*
ntfs_runlists_merge
(
runlist_element
*
drl
,
...
...
@@ -76,14 +78,22 @@ extern runlist_element *ntfs_mapping_pairs_decompress(const ntfs_volume *vol,
extern
LCN
ntfs_rl_vcn_to_lcn
(
const
runlist_element
*
rl
,
const
VCN
vcn
);
#ifdef NTFS_RW
extern
runlist_element
*
ntfs_rl_find_vcn_nolock
(
runlist_element
*
rl
,
const
VCN
vcn
);
extern
int
ntfs_get_size_for_mapping_pairs
(
const
ntfs_volume
*
vol
,
const
runlist_element
*
rl
,
const
VCN
start_vcn
);
const
runlist_element
*
rl
,
const
VCN
first_vcn
,
const
VCN
last_vcn
);
extern
int
ntfs_mapping_pairs_build
(
const
ntfs_volume
*
vol
,
s8
*
dst
,
const
int
dst_len
,
const
runlist_element
*
rl
,
const
VCN
star
t_vcn
,
VCN
*
const
stop_vcn
);
const
VCN
first_vcn
,
const
VCN
las
t_vcn
,
VCN
*
const
stop_vcn
);
extern
int
ntfs_rl_truncate_nolock
(
const
ntfs_volume
*
vol
,
runlist
*
const
runlist
,
const
s64
new_length
);
#endif
/* NTFS_RW */
#endif
/* _LINUX_NTFS_RUNLIST_H */
fs/ntfs/super.c
浏览文件 @
076fb01e
此差异已折叠。
点击以展开。
fs/ntfs/sysctl.c
浏览文件 @
076fb01e
...
...
@@ -3,7 +3,7 @@
* the Linux-NTFS project. Adapted from the old NTFS driver,
* Copyright (C) 1997 Martin von Lwis, Rgis Duchesne
*
* Copyright (c) 2002-200
4
Anton Altaparmakov
* Copyright (c) 2002-200
5
Anton Altaparmakov
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
...
...
@@ -67,7 +67,7 @@ int ntfs_sysctl(int add)
return
-
ENOMEM
;
#ifdef CONFIG_PROC_FS
/*
* If the proc file
system is in use and we are a module, need
* If the proc filesystem is in use and we are a module, need
* to set the owner of our proc entry to our module. In the
* non-modular case, THIS_MODULE is NULL, so this is ok.
*/
...
...
fs/ntfs/time.h
浏览文件 @
076fb01e
/*
* time.h - NTFS time conversion functions. Part of the Linux-NTFS project.
*
* Copyright (c) 2001-200
4
Anton Altaparmakov
* Copyright (c) 2001-200
5
Anton Altaparmakov
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
...
...
@@ -87,7 +87,7 @@ static inline struct timespec ntfs2utc(const sle64 time)
struct
timespec
ts
;
/* Subtract the NTFS time offset. */
s64
t
=
sle64_to_cpu
(
time
)
-
NTFS_TIME_OFFSET
;
u64
t
=
(
u64
)(
sle64_to_cpu
(
time
)
-
NTFS_TIME_OFFSET
)
;
/*
* Convert the time to 1-second intervals and the remainder to
* 1-nano-second intervals.
...
...
fs/ntfs/types.h
浏览文件 @
076fb01e
...
...
@@ -2,7 +2,7 @@
* types.h - Defines for NTFS Linux kernel driver specific types.
* Part of the Linux-NTFS project.
*
* Copyright (c) 2001-200
4
Anton Altaparmakov
* Copyright (c) 2001-200
5
Anton Altaparmakov
*
* This program/include file is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published
...
...
@@ -53,6 +53,14 @@ typedef sle64 leLCN;
typedef
s64
LSN
;
typedef
sle64
leLSN
;
/*
* The NTFS transaction log $UsnJrnl uses usn which are signed 64-bit values.
* We define our own type USN, to allow for type checking and better code
* readability.
*/
typedef
s64
USN
;
typedef
sle64
leUSN
;
typedef
enum
{
FALSE
=
0
,
TRUE
=
1
...
...
fs/ntfs/unistr.c
浏览文件 @
076fb01e
...
...
@@ -264,7 +264,7 @@ int ntfs_nlstoucs(const ntfs_volume *vol, const char *ins,
/* We don't trust outside sources. */
if
(
ins
)
{
ucs
=
(
ntfschar
*
)
kmem_cache_alloc
(
ntfs_name_cache
,
SLAB_NOFS
);
ucs
=
kmem_cache_alloc
(
ntfs_name_cache
,
SLAB_NOFS
);
if
(
ucs
)
{
for
(
i
=
o
=
0
;
i
<
ins_len
;
i
+=
wc_len
)
{
wc_len
=
nls
->
char2uni
(
ins
+
i
,
ins_len
-
i
,
...
...
fs/ntfs/usnjrnl.c
0 → 100644
浏览文件 @
076fb01e
此差异已折叠。
点击以展开。
fs/ntfs/usnjrnl.h
0 → 100644
浏览文件 @
076fb01e
此差异已折叠。
点击以展开。
fs/ntfs/volume.h
浏览文件 @
076fb01e
...
...
@@ -2,7 +2,7 @@
* volume.h - Defines for volume structures in NTFS Linux kernel driver. Part
* of the Linux-NTFS project.
*
* Copyright (c) 2001-200
4
Anton Altaparmakov
* Copyright (c) 2001-200
5
Anton Altaparmakov
* Copyright (c) 2002 Richard Russon
*
* This program/include file is free software; you can redistribute it and/or
...
...
@@ -54,7 +54,7 @@ typedef struct {
mode_t
dmask
;
/* The mask for directory
permissions. */
u8
mft_zone_multiplier
;
/* Initial mft zone multiplier. */
u8
on_errors
;
/* What to do on file
system errors. */
u8
on_errors
;
/* What to do on filesystem errors. */
/* NTFS bootsector provided information. */
u16
sector_size
;
/* in bytes */
u8
sector_size_bits
;
/* log2(sector_size) */
...
...
@@ -125,6 +125,10 @@ typedef struct {
/* $Quota stuff is NTFS3.0+ specific. Unused/NULL otherwise. */
struct
inode
*
quota_ino
;
/* The VFS inode of $Quota. */
struct
inode
*
quota_q_ino
;
/* Attribute inode for $Quota/$Q. */
/* $UsnJrnl stuff is NTFS3.0+ specific. Unused/NULL otherwise. */
struct
inode
*
usnjrnl_ino
;
/* The VFS inode of $UsnJrnl. */
struct
inode
*
usnjrnl_max_ino
;
/* Attribute inode for $UsnJrnl/$Max. */
struct
inode
*
usnjrnl_j_ino
;
/* Attribute inode for $UsnJrnl/$J. */
#endif
/* NTFS_RW */
struct
nls_table
*
nls_map
;
}
ntfs_volume
;
...
...
@@ -141,6 +145,8 @@ typedef enum {
file names in WIN32 namespace. */
NV_LogFileEmpty
,
/* 1: $LogFile journal is empty. */
NV_QuotaOutOfDate
,
/* 1: $Quota is out of date. */
NV_UsnJrnlStamped
,
/* 1: $UsnJrnl has been stamped. */
NV_SparseEnabled
,
/* 1: May create sparse files. */
}
ntfs_volume_flags
;
/*
...
...
@@ -167,5 +173,7 @@ NVOL_FNS(ShowSystemFiles)
NVOL_FNS
(
CaseSensitive
)
NVOL_FNS
(
LogFileEmpty
)
NVOL_FNS
(
QuotaOutOfDate
)
NVOL_FNS
(
UsnJrnlStamped
)
NVOL_FNS
(
SparseEnabled
)
#endif
/* _LINUX_NTFS_VOLUME_H */
include/asm-arm/arch-shark/io.h
浏览文件 @
076fb01e
此差异已折叠。
点击以展开。
include/linux/serial.h
浏览文件 @
076fb01e
此差异已折叠。
点击以展开。
include/linux/serialP.h
浏览文件 @
076fb01e
此差异已折叠。
点击以展开。
include/linux/serial_core.h
浏览文件 @
076fb01e
此差异已折叠。
点击以展开。
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录