···103103---------------------------104104105105What: register_serial/unregister_serial106106-When: December 2005106106+When: September 2005107107Why: This interface does not allow serial ports to be registered against108108 a struct device, and as such does not allow correct power management109109 of such ports. 8250-based ports should use serial8250_register_port110110- and serial8250_unregister_port instead.110110+ and serial8250_unregister_port, or platform devices instead.111111Who: Russell King <rmk@arm.linux.org.uk>112112113113---------------------------
+45-32
Documentation/filesystems/inotify.txt
···11- inotify22- a powerful yet simple file change notification system11+ inotify22+ a powerful yet simple file change notification system33445566Document started 15 Mar 2005 by Robert Love <rml@novell.com>7788+89(i) User Interface9101010-Inotify is controlled by a set of three sys calls 1111+Inotify is controlled by a set of three system calls and normal file I/O on a1212+returned file descriptor.11131212-First step in using inotify is to initialise an inotify instance1414+First step in using inotify is to initialise an inotify instance:13151416 int fd = inotify_init ();1717+1818+Each instance is associated with a unique, ordered queue.15191620Change events are managed by "watches". A watch is an (object,mask) pair where1721the object is a file or directory and the mask is a bit mask of one or more···26222723Watches on a directory will return events on any files inside of the directory.28242929-Adding a watch is simple,2525+Adding a watch is simple:30263127 int wd = inotify_add_watch (fd, path, mask);32283333-You can add a large number of files via something like3434-3535- for each file to watch {3636- int wd = inotify_add_watch (fd, file, mask);3737- }2929+Where "fd" is the return value from inotify_init(), path is the path to the3030+object to watch, and mask is the watch mask (see <linux/inotify.h>).38313932You can update an existing watch in the same manner, by passing in a new mask.40334141-An existing watch is removed via the INOTIFY_IGNORE ioctl, for example3434+An existing watch is removed via42354343- inotify_rm_watch (fd, wd);3636+ int ret = inotify_rm_watch (fd, wd);44374538Events are provided in the form of an inotify_event structure that is read(2)4646-from a inotify instance fd. The filename is of dynamic length and follows the 4747-struct. It is of size len. The filename is padded with null bytes to ensure 4848-proper alignment. This padding is reflected in len.3939+from a given inotify instance. The filename is of dynamic length and follows4040+the struct. It is of size len. The filename is padded with null bytes to4141+ensure proper alignment. This padding is reflected in len.49425043You can slurp multiple events by passing a large buffer, for example51445245 size_t len = read (fd, buf, BUF_LEN);53465454-Will return as many events as are available and fit in BUF_LEN.4747+Where "buf" is a pointer to an array of "inotify_event" structures at least4848+BUF_LEN bytes in size. The above example will return as many events as are4949+available and fit in BUF_LEN.55505656-each inotify instance fd is also select()- and poll()-able.5151+Each inotify instance fd is also select()- and poll()-able.57525858-You can find the size of the current event queue via the FIONREAD ioctl.5353+You can find the size of the current event queue via the standard FIONREAD5454+ioctl on the fd returned by inotify_init().59556056All watches are destroyed and cleaned up on close.615762586363-(ii) Internal Kernel Implementation5959+(ii)64606565-Each open inotify instance is associated with an inotify_device structure.6161+Prototypes:6262+6363+ int inotify_init (void);6464+ int inotify_add_watch (int fd, const char *path, __u32 mask);6565+ int inotify_rm_watch (int fd, __u32 mask);6666+6767+6868+(iii) Internal Kernel Implementation6969+7070+Each inotify instance is associated with an inotify_device structure.66716772Each watch is associated with an inotify_watch structure. Watches are chained6873off of each associated device and each associated inode.···7966See fs/inotify.c for the locking and lifetime rules.806781688282-(iii) Rationale6969+(iv) Rationale83708471Q: What is the design decision behind not tying the watch to the open fd of8572 the watched object?···8875 This solves the primary problem with dnotify: keeping the file open pins8976 the file and thus, worse, pins the mount. Dnotify is therefore infeasible9077 for use on a desktop system with removable media as the media cannot be9191- unmounted.7878+ unmounted. Watching a file should not require that it be open.92799393-Q: What is the design decision behind using an-fd-per-device as opposed to8080+Q: What is the design decision behind using an-fd-per-instance as opposed to9481 an fd-per-watch?95829683A: An fd-per-watch quickly consumes more file descriptors than are allowed,···9986 can use epoll, but requiring both is a silly and extraneous requirement.10087 A watch consumes less memory than an open file, separating the number10188 spaces is thus sensible. The current design is what user-space developers102102- want: Users initialize inotify, once, and add n watches, requiring but one fd103103- and no twiddling with fd limits. Initializing an inotify instance two8989+ want: Users initialize inotify, once, and add n watches, requiring but one9090+ fd and no twiddling with fd limits. Initializing an inotify instance two10491 thousand times is silly. If we can implement user-space's preferences 10592 cleanly--and we can, the idr layer makes stuff like this trivial--then we 10693 should.···124111 example, love it. Trust me, I asked. It is not a surprise: Who'd want125112 to manage and block on 1000 fd's via select?126113127127- - You'd have to manage the fd's, as an example: Call close() when you128128- received a delete event.129129-130114 - No way to get out of band data.131115132116 - 1024 is still too low. ;-)···131121 When you talk about designing a file change notification system that132122 scales to 1000s of directories, juggling 1000s of fd's just does not seem133123 the right interface. It is too heavy.124124+125125+ Additionally, it _is_ possible to more than one instance and126126+ juggle more than one queue and thus more than one associated fd. There127127+ need not be a one-fd-per-process mapping; it is one-fd-per-queue and a128128+ process can easily want more than one queue.134129135130Q: Why the system call approach?136131···146131 Obtaining the fd and managing the watches could have been done either via a147132 device file or a family of new system calls. We decided to implement a148133 family of system calls because that is the preffered approach for new kernel149149- features and it means our user interface requirements.150150-151151- Additionally, it _is_ possible to more than one instance and152152- juggle more than one queue and thus more than one associated fd.134134+ interfaces. The only real difference was whether we wanted to use open(2)135135+ and ioctl(2) or a couple of new system calls. System calls beat ioctls.153136
+27-2
Documentation/filesystems/ntfs.txt
···2121========22222323Linux-NTFS comes with a number of user-space programs known as ntfsprogs.2424-These include mkntfs, a full-featured ntfs file system format utility,2424+These include mkntfs, a full-featured ntfs filesystem format utility,2525ntfsundelete used for recovering files that were unintentionally deleted2626from an NTFS volume and ntfsresize which is used to resize an NTFS partition.2727See the web site for more information.···149149 name, if it exists. If case_sensitive, you will need150150 to provide the correct case of the short file name.151151152152-errors=opt What to do when critical file system errors are found.152152+disable_sparse=<BOOL> If disable_sparse is specified, creation of sparse153153+ regions, i.e. holes, inside files is disabled for the154154+ volume (for the duration of this mount only). By155155+ default, creation of sparse regions is enabled, which156156+ is consistent with the behaviour of traditional Unix157157+ filesystems.158158+159159+errors=opt What to do when critical filesystem errors are found.153160 Following values can be used for "opt":154161 continue: DEFAULT, try to clean-up as much as155162 possible, e.g. marking a corrupt inode as···439432440433Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog.441434435435+2.1.23:436436+ - Stamp the user space journal, aka transaction log, aka $UsnJrnl, if437437+ it is present and active thus telling Windows and applications using438438+ the transaction log that changes can have happened on the volume439439+ which are not recorded in $UsnJrnl.440440+ - Detect the case when Windows has been hibernated (suspended to disk)441441+ and if this is the case do not allow (re)mounting read-write to442442+ prevent data corruption when you boot back into the suspended443443+ Windows session.444444+ - Implement extension of resident files using the normal file write445445+ code paths, i.e. most very small files can be extended to be a little446446+ bit bigger but not by much.447447+ - Add new mount option "disable_sparse". (See list of mount options448448+ above for details.)449449+ - Improve handling of ntfs volumes with errors and strange boot sectors450450+ in particular.451451+ - Fix various bugs including a nasty deadlock that appeared in recent452452+ kernels (around 2.6.11-2.6.12 timeframe).4424532.1.22:443454 - Improve handling of ntfs volumes with errors.444455 - Fix various bugs and race conditions.
+12
MAINTAINERS
···11721172L: linux-joystick@atrey.karlin.mff.cuni.cz11731173S: Maintained1174117411751175+INOTIFY11761176+P: John McCutchan and Robert Love11771177+M: ttb@tentacle.dhs.org and rml@novell.com11781178+L: linux-kernel@vger.kernel.org11791179+S: Maintained11801180+11751181INTEL 810/815 FRAMEBUFFER DRIVER11761182P: Antonino Daplas11771183M: adaplas@pol.net···24262420P: Roman Weissgaerber24272421M: weissg@vienna.at24282422L: linux-usb-users@lists.sourceforge.net24232423+L: linux-usb-devel@lists.sourceforge.net24242424+S: Maintained24252425+24262426+USB OPTION-CARD DRIVER24272427+P: Matthias Urlichs24282428+M: smurf@smurf.noris.de24292429L: linux-usb-devel@lists.sourceforge.net24302430S: Maintained24312431
+52-33
arch/arm/configs/shark_defconfig
···11#22# Automatically generated make config: don't edit33-# Linux kernel version: 2.6.12-rc1-bk244-# Sun Mar 27 23:59:14 200533+# Linux kernel version: 2.6.12-git344+# Sat Jul 16 15:21:47 200555#66CONFIG_ARM=y77CONFIG_MMU=y88CONFIG_UID16=y99CONFIG_RWSEM_GENERIC_SPINLOCK=y1010CONFIG_GENERIC_CALIBRATE_DELAY=y1111-CONFIG_GENERIC_IOMAP=y12111312#1413# Code maturity level options1514#1615CONFIG_EXPERIMENTAL=y1717-# CONFIG_CLEAN_COMPILE is not set1818-CONFIG_BROKEN=y1616+CONFIG_CLEAN_COMPILE=y1917CONFIG_BROKEN_ON_SMP=y1818+CONFIG_INIT_ENV_ARG_LIMIT=3220192120#2221# General setup···3233# CONFIG_IKCONFIG is not set3334# CONFIG_EMBEDDED is not set3435CONFIG_KALLSYMS=y3636+# CONFIG_KALLSYMS_ALL is not set3537# CONFIG_KALLSYMS_EXTRA_PASS is not set3838+CONFIG_PRINTK=y3939+CONFIG_BUG=y3640CONFIG_BASE_FULL=y3741CONFIG_FUTEX=y3842CONFIG_EPOLL=y···8381# CONFIG_ARCH_VERSATILE is not set8482# CONFIG_ARCH_IMX is not set8583# CONFIG_ARCH_H720X is not set8484+# CONFIG_ARCH_AAEC2000 is not set86858786#8887# Processor Type···106103#107104CONFIG_ISA=y108105CONFIG_ISA_DMA=y106106+CONFIG_ISA_DMA_API=y109107CONFIG_PCI=y110108CONFIG_PCI_HOST_VIA82C505=y111109CONFIG_PCI_LEGACY_PROC=y112110# CONFIG_PCI_NAMES is not set111111+# CONFIG_PCI_DEBUG is not set113112114113#115114# PCCARD (PCMCIA/CardBus) support···121116#122117# Kernel Features123118#119119+# CONFIG_SMP is not set124120# CONFIG_PREEMPT is not set121121+# CONFIG_DISCONTIGMEM is not set125122CONFIG_LEDS=y126123CONFIG_LEDS_TIMER=y127124# CONFIG_LEDS_CPU is not set···170163# CONFIG_STANDALONE is not set171164CONFIG_PREVENT_FIRMWARE_BUILD=y172165# CONFIG_FW_LOADER is not set166166+# CONFIG_DEBUG_DRIVER is not set173167174168#175169# Memory Technology Devices (MTD)···180172#181173# Parallel port support182174#183183-CONFIG_PARPORT=y184184-CONFIG_PARPORT_PC=y175175+CONFIG_PARPORT=m176176+CONFIG_PARPORT_PC=m185177# CONFIG_PARPORT_SERIAL is not set186178# CONFIG_PARPORT_PC_FIFO is not set187179# CONFIG_PARPORT_PC_SUPERIO is not set···197189#198190# Block devices199191#200200-# CONFIG_BLK_DEV_FD is not set201192# CONFIG_BLK_DEV_XD is not set202193# CONFIG_PARIDE is not set203194# CONFIG_BLK_CPQ_DA is not set···236229# CONFIG_BLK_DEV_IDE_SATA is not set237230CONFIG_BLK_DEV_IDEDISK=y238231# CONFIG_IDEDISK_MULTI_MODE is not set239239-CONFIG_BLK_DEV_IDECD=y232232+CONFIG_BLK_DEV_IDECD=m240233# CONFIG_BLK_DEV_IDETAPE is not set241234CONFIG_BLK_DEV_IDEFLOPPY=y242235# CONFIG_BLK_DEV_IDESCSI is not set···268261CONFIG_BLK_DEV_SR=m269262# CONFIG_BLK_DEV_SR_VENDOR is not set270263CONFIG_CHR_DEV_SG=m264264+# CONFIG_CHR_DEV_SCH is not set271265272266#273267# Some SCSI devices (e.g. CD jukebox) support multiple LUNs···298290# CONFIG_SCSI_AIC7XXX_OLD is not set299291# CONFIG_SCSI_AIC79XX is not set300292# CONFIG_SCSI_DPT_I2O is not set301301-# CONFIG_SCSI_ADVANSYS is not set302293# CONFIG_SCSI_IN2000 is not set303294# CONFIG_MEGARAID_NEWGEN is not set304295# CONFIG_MEGARAID_LEGACY is not set305296# CONFIG_SCSI_SATA is not set306297# CONFIG_SCSI_BUSLOGIC is not set307307-# CONFIG_SCSI_CPQFCTS is not set308298# CONFIG_SCSI_DMX3191D is not set309299# CONFIG_SCSI_DTC3280 is not set310300# CONFIG_SCSI_EATA is not set311311-# CONFIG_SCSI_EATA_PIO is not set312301# CONFIG_SCSI_FUTURE_DOMAIN is not set313302# CONFIG_SCSI_GDTH is not set314303# CONFIG_SCSI_GENERIC_NCR5380 is not set···319314# CONFIG_SCSI_SYM53C8XX_2 is not set320315# CONFIG_SCSI_IPR is not set321316# CONFIG_SCSI_PAS16 is not set322322-# CONFIG_SCSI_PCI2000 is not set323323-# CONFIG_SCSI_PCI2220I is not set324317# CONFIG_SCSI_PSI240I is not set325318# CONFIG_SCSI_QLOGIC_FAS is not set326326-# CONFIG_SCSI_QLOGIC_ISP is not set327319# CONFIG_SCSI_QLOGIC_FC is not set328320# CONFIG_SCSI_QLOGIC_1280 is not set329321CONFIG_SCSI_QLA2XXX=m···329327# CONFIG_SCSI_QLA2300 is not set330328# CONFIG_SCSI_QLA2322 is not set331329# CONFIG_SCSI_QLA6312 is not set330330+# CONFIG_SCSI_LPFC is not set332331# CONFIG_SCSI_SYM53C416 is not set333332# CONFIG_SCSI_DC395x is not set334333# CONFIG_SCSI_DC390T is not set···347344# Fusion MPT device support348345#349346# CONFIG_FUSION is not set347347+# CONFIG_FUSION_SPI is not set348348+# CONFIG_FUSION_FC is not set350349351350#352351# IEEE 1394 (FireWire) support···370365#371366CONFIG_PACKET=y372367# CONFIG_PACKET_MMAP is not set373373-# CONFIG_NETLINK_DEV is not set374368CONFIG_UNIX=y375369# CONFIG_NET_KEY is not set376370CONFIG_INET=y···384380# CONFIG_INET_ESP is not set385381# CONFIG_INET_IPCOMP is not set386382# CONFIG_INET_TUNNEL is not set387387-# CONFIG_IP_TCPDIAG is not set383383+CONFIG_IP_TCPDIAG=y388384# CONFIG_IP_TCPDIAG_IPV6 is not set389385# CONFIG_IPV6 is not set390386# CONFIG_NETFILTER is not set···443439# CONFIG_LANCE is not set444440# CONFIG_NET_VENDOR_SMC is not set445441# CONFIG_SMC91X is not set442442+# CONFIG_DM9000 is not set446443# CONFIG_NET_VENDOR_RACAL is not set447444448445#···488483# CONFIG_HAMACHI is not set489484# CONFIG_YELLOWFIN is not set490485# CONFIG_R8169 is not set486486+# CONFIG_SKGE is not set491487# CONFIG_SK98LIN is not set492488# CONFIG_VIA_VELOCITY is not set493489# CONFIG_TIGON3 is not set490490+# CONFIG_BNX2 is not set494491495492#496493# Ethernet (10000 Mbit)···576569CONFIG_SERIO_LIBPS2=y577570# CONFIG_SERIO_RAW is not set578571# CONFIG_GAMEPORT is not set579579-CONFIG_SOUND_GAMEPORT=y580572581573#582574# Character devices···598592#599593CONFIG_SERIAL_CORE=y600594CONFIG_SERIAL_CORE_CONSOLE=y595595+# CONFIG_SERIAL_JSM is not set601596CONFIG_UNIX98_PTYS=y602597CONFIG_LEGACY_PTYS=y603598CONFIG_LEGACY_PTY_COUNT=256···660653CONFIG_FB_CFB_COPYAREA=y661654CONFIG_FB_CFB_IMAGEBLIT=y662655CONFIG_FB_SOFT_CURSOR=y656656+# CONFIG_FB_MACMODES is not set663657# CONFIG_FB_MODE_HELPERS is not set664658# CONFIG_FB_TILEBLITTING is not set665659# CONFIG_FB_CIRRUS is not set···682674# CONFIG_FB_3DFX is not set683675# CONFIG_FB_VOODOO1 is not set684676# CONFIG_FB_TRIDENT is not set685685-# CONFIG_FB_PM3 is not set677677+# CONFIG_FB_S1D13XXX is not set686678# CONFIG_FB_VIRTUAL is not set687679688680#···816808#817809# CD-ROM/DVD Filesystems818810#819819-CONFIG_ISO9660_FS=y811811+CONFIG_ISO9660_FS=m820812CONFIG_JOLIET=y821813# CONFIG_ZISOFS is not set822814# CONFIG_UDF_FS is not set···824816#825817# DOS/FAT/NT Filesystems826818#827827-CONFIG_FAT_FS=y828828-CONFIG_MSDOS_FS=y829829-CONFIG_VFAT_FS=y819819+CONFIG_FAT_FS=m820820+CONFIG_MSDOS_FS=m821821+CONFIG_VFAT_FS=m830822CONFIG_FAT_DEFAULT_CODEPAGE=437831823CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"832824# CONFIG_NTFS_FS is not set···841833# CONFIG_DEVFS_DEBUG is not set842834# CONFIG_DEVPTS_FS_XATTR is not set843835# CONFIG_TMPFS is not set844844-# CONFIG_HUGETLBFS is not set845836# CONFIG_HUGETLB_PAGE is not set846837CONFIG_RAMFS=y847838···864857#865858# Network File Systems866859#867867-CONFIG_NFS_FS=y868868-# CONFIG_NFS_V3 is not set860860+CONFIG_NFS_FS=m861861+CONFIG_NFS_V3=y869862# CONFIG_NFS_V4 is not set870863# CONFIG_NFS_DIRECTIO is not set871864# CONFIG_NFSD is not set872872-CONFIG_LOCKD=y873873-CONFIG_SUNRPC=y865865+CONFIG_LOCKD=m866866+CONFIG_LOCKD_V4=y867867+CONFIG_SUNRPC=m874868# CONFIG_RPCSEC_GSS_KRB5 is not set875869# CONFIG_RPCSEC_GSS_SPKM3 is not set876870# CONFIG_SMB_FS is not set···903895#904896# Native Language Support905897#906906-CONFIG_NLS=y898898+CONFIG_NLS=m907899CONFIG_NLS_DEFAULT="iso8859-1"908908-CONFIG_NLS_CODEPAGE_437=y900900+CONFIG_NLS_CODEPAGE_437=m909901# CONFIG_NLS_CODEPAGE_737 is not set910902# CONFIG_NLS_CODEPAGE_775 is not set911911-CONFIG_NLS_CODEPAGE_850=y903903+CONFIG_NLS_CODEPAGE_850=m912904# CONFIG_NLS_CODEPAGE_852 is not set913905# CONFIG_NLS_CODEPAGE_855 is not set914906# CONFIG_NLS_CODEPAGE_857 is not set···929921# CONFIG_NLS_CODEPAGE_1250 is not set930922# CONFIG_NLS_CODEPAGE_1251 is not set931923# CONFIG_NLS_ASCII is not set932932-CONFIG_NLS_ISO8859_1=y924924+CONFIG_NLS_ISO8859_1=m933925# CONFIG_NLS_ISO8859_2 is not set934926# CONFIG_NLS_ISO8859_3 is not set935927# CONFIG_NLS_ISO8859_4 is not set···953945# Kernel hacking954946#955947# CONFIG_PRINTK_TIME is not set956956-# CONFIG_DEBUG_KERNEL is not set948948+CONFIG_DEBUG_KERNEL=y949949+# CONFIG_MAGIC_SYSRQ is not set957950CONFIG_LOG_BUF_SHIFT=14951951+# CONFIG_SCHEDSTATS is not set952952+# CONFIG_DEBUG_SLAB is not set953953+# CONFIG_DEBUG_SPINLOCK is not set954954+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set955955+# CONFIG_DEBUG_KOBJECT is not set958956CONFIG_DEBUG_BUGVERBOSE=y957957+# CONFIG_DEBUG_INFO is not set958958+# CONFIG_DEBUG_FS is not set959959CONFIG_FRAME_POINTER=y960960CONFIG_DEBUG_USER=y961961+# CONFIG_DEBUG_WAITQ is not set962962+# CONFIG_DEBUG_ERRORS is not set963963+# CONFIG_DEBUG_LL is not set961964962965#963966# Security options
+4-3
arch/arm/kernel/smp.c
···3636 * The present bitmask indicates that the CPU is physically present.3737 * The online bitmask indicates that the CPU is up and running.3838 */3939-cpumask_t cpu_present_mask;3939+cpumask_t cpu_possible_map;4040cpumask_t cpu_online_map;41414242/*···235235{236236 unsigned int cpu = smp_processor_id();237237238238- cpu_set(cpu, cpu_present_mask);238238+ cpu_set(cpu, cpu_possible_map);239239+ cpu_set(cpu, cpu_present_map);239240 cpu_set(cpu, cpu_online_map);240241}241242···356355357356 seq_puts(p, "IPI:");358357359359- for_each_online_cpu(cpu)358358+ for_each_present_cpu(cpu)360359 seq_printf(p, " %10lu", per_cpu(ipi_data, cpu).ipi_count);361360362361 seq_putc(p, '\n');
···1111 * it under the terms of the GNU General Public License version 2 as1212 * published by the Free Software Foundation.1313 */1414-#include <linux/kernel.h>1515-1616-#include <asm/io.h>1717-1818-void print_warning(void)1919-{2020- printk(KERN_WARNING "ins?/outs? not implemented on this architecture\n");2121-}2222-2323-void insl(unsigned int port, void *to, int len)2424-{2525- print_warning();2626-}2727-2828-void insb(unsigned int port, void *to, int len)2929-{3030- print_warning();3131-}3232-3333-void outsl(unsigned int port, const void *from, int len)3434-{3535- print_warning();3636-}3737-3838-void outsb(unsigned int port, const void *from, int len)3939-{4040- print_warning();4141-}4242-4343-/* these should be in assembler again */4444-4545-/*4646- * Purpose: read a block of data from a hardware register to memory.4747- * Proto : insw(int from_port, void *to, int len_in_words);4848- * Proto : inswb(int from_port, void *to, int len_in_bytes);4949- * Notes : increment to5050- */5151-5252-void insw(unsigned int port, void *to, int len)5353-{5454- int i;5555-5656- for (i = 0; i < len; i++)5757- ((unsigned short *) to)[i] = inw(port);5858-}5959-6060-void inswb(unsigned int port, void *to, int len)6161-{6262- insw(port, to, len >> 2);6363-}6464-6565-/*6666- * Purpose: write a block of data from memory to a hardware register.6767- * Proto : outsw(int to_reg, void *from, int len_in_words);6868- * Proto : outswb(int to_reg, void *from, int len_in_bytes);6969- * Notes : increments from7070- */7171-7272-void outsw(unsigned int port, const void *from, int len)7373-{7474- int i;7575-7676- for (i = 0; i < len; i++)7777- outw(((unsigned short *) from)[i], port);7878-}7979-8080-void outswb(unsigned int port, const void *from, int len)8181-{8282- outsw(port, from, len >> 2);8383-}
+5-3
arch/arm/mach-integrator/platsmp.c
···174174 max_cpus = ncores;175175176176 /*177177- * Initialise the present mask - this tells us which CPUs should178178- * be present.177177+ * Initialise the possible/present maps.178178+ * cpu_possible_map describes the set of CPUs which may be present179179+ * cpu_present_map describes the set of CPUs populated179180 */180181 for (i = 0; i < max_cpus; i++) {181181- cpu_set(i, cpu_present_mask);182182+ cpu_set(i, cpu_possible_map);183183+ cpu_set(i, cpu_present_map);182184 }183185184186 /*
···3636 * Power off function, if any3737 */3838void (*pm_power_off)(void);3939+EXPORT_SYMBOL(pm_power_off);39404041int voyager_level = 0;4142
+6
arch/i386/mach-voyager/voyager_smp.c
···1010 * the voyager hal to provide the functionality1111 */1212#include <linux/config.h>1313+#include <linux/module.h>1314#include <linux/mm.h>1415#include <linux/kernel_stat.h>1516#include <linux/delay.h>···4140/* per CPU data structure (for /proc/cpuinfo et al), visible externally4241 * indexed physically */4342struct cpuinfo_x86 cpu_data[NR_CPUS] __cacheline_aligned;4343+EXPORT_SYMBOL(cpu_data);44444545/* physical ID of the CPU used to boot the system */4646unsigned char boot_cpu_id;···7472/* Bitmask of currently online CPUs - used by setup.c for7573 /proc/cpuinfo, visible externally but still physical */7674cpumask_t cpu_online_map = CPU_MASK_NONE;7575+EXPORT_SYMBOL(cpu_online_map);77767877/* Bitmask of CPUs present in the system - exported by i386_syms.c, used7978 * by scheduler but indexed physically */···241238/* This is for the new dynamic CPU boot code */242239cpumask_t cpu_callin_map = CPU_MASK_NONE;243240cpumask_t cpu_callout_map = CPU_MASK_NONE;241241+EXPORT_SYMBOL(cpu_callout_map);244242245243/* The per processor IRQ masks (these are usually kept in sync) */246244static __u16 vic_irq_mask[NR_CPUS] __cacheline_aligned;···982978983979 preempt_enable();984980}981981+EXPORT_SYMBOL(flush_tlb_page);985982986983/* enable the requested IRQs */987984static void···1114110911151110 return 0;11161111}11121112+EXPORT_SYMBOL(smp_call_function);1117111311181114/* Sorry about the name. In an APIC based system, the APICs11191115 * themselves are programmed to send a timer interrupt. This is used
-7
arch/ia64/Kconfig
···220220 depends on !IA64_HP_SIM221221 default y222222223223-config IA64_SGI_SN_SIM224224- bool "SGI Medusa Simulator Support"225225- depends on IA64_SGI_SN2 || IA64_GENERIC226226- help227227- If you are compiling a kernel that will run under SGI's IA-64228228- simulator (Medusa) then say Y, otherwise say N.229229-230223config IA64_SGI_SN_XP231224 tristate "Support communication between SGI SSIs"232225 select IA64_UNCACHED_ALLOCATOR
-1
arch/ia64/configs/sn2_defconfig
···8181CONFIG_ARCH_DISCONTIGMEM_ENABLE=y8282# CONFIG_IA64_CYCLONE is not set8383CONFIG_IOSAPIC=y8484-CONFIG_IA64_SGI_SN_SIM=y8584CONFIG_FORCE_MAX_ZONEORDER=188685CONFIG_SMP=y8786CONFIG_NR_CPUS=512
+35-2
arch/ia64/kernel/setup.c
···2020 * 02/01/00 R.Seth fixed get_cpuinfo for SMP2121 * 01/07/99 S.Eranian added the support for command line argument2222 * 06/24/99 W.Drummond added boot_cpu_data.2323+ * 05/28/05 Z. Menyhart Dynamic stride size for "flush_icache_range()"2324 */2425#include <linux/config.h>2526#include <linux/module.h>···8483struct io_space io_space[MAX_IO_SPACES];8584EXPORT_SYMBOL(io_space);8685unsigned int num_io_spaces;8686+8787+/*8888+ * "flush_icache_range()" needs to know what processor dependent stride size to use8989+ * when it makes i-cache(s) coherent with d-caches.9090+ */9191+#define I_CACHE_STRIDE_SHIFT 5 /* Safest way to go: 32 bytes by 32 bytes */9292+unsigned long ia64_i_cache_stride_shift = ~0;87938894/*8995 * The merge_mask variable needs to be set to (max(iommu_page_size(iommu)) - 1). This···636628 /* start_kernel() requires this... */637629}638630631631+/*632632+ * Calculate the max. cache line size.633633+ *634634+ * In addition, the minimum of the i-cache stride sizes is calculated for635635+ * "flush_icache_range()".636636+ */639637static void640638get_max_cacheline_size (void)641639{···655641 printk(KERN_ERR "%s: ia64_pal_cache_summary() failed (status=%ld)\n",656642 __FUNCTION__, status);657643 max = SMP_CACHE_BYTES;644644+ /* Safest setup for "flush_icache_range()" */645645+ ia64_i_cache_stride_shift = I_CACHE_STRIDE_SHIFT;658646 goto out;659647 }660648···665649 &cci);666650 if (status != 0) {667651 printk(KERN_ERR668668- "%s: ia64_pal_cache_config_info(l=%lu) failed (status=%ld)\n",652652+ "%s: ia64_pal_cache_config_info(l=%lu, 2) failed (status=%ld)\n",669653 __FUNCTION__, l, status);670654 max = SMP_CACHE_BYTES;655655+ /* The safest setup for "flush_icache_range()" */656656+ cci.pcci_stride = I_CACHE_STRIDE_SHIFT;657657+ cci.pcci_unified = 1;671658 }672659 line_size = 1 << cci.pcci_line_size;673660 if (line_size > max)674661 max = line_size;675675- }662662+ if (!cci.pcci_unified) {663663+ status = ia64_pal_cache_config_info(l,664664+ /* cache_type (instruction)= */ 1,665665+ &cci);666666+ if (status != 0) {667667+ printk(KERN_ERR668668+ "%s: ia64_pal_cache_config_info(l=%lu, 1) failed (status=%ld)\n",669669+ __FUNCTION__, l, status);670670+ /* The safest setup for "flush_icache_range()" */671671+ cci.pcci_stride = I_CACHE_STRIDE_SHIFT;672672+ }673673+ }674674+ if (cci.pcci_stride < ia64_i_cache_stride_shift)675675+ ia64_i_cache_stride_shift = cci.pcci_stride;676676+ }676677 out:677678 if (max > ia64_max_cacheline_size)678679 ia64_max_cacheline_size = max;
+2
arch/ia64/kernel/topology.c
···3636 parent = &sysfs_nodes[cpu_to_node(num)];3737#endif /* CONFIG_NUMA */38383939+#ifdef CONFIG_ACPI_BOOT3940 /*4041 * If CPEI cannot be re-targetted, and this is4142 * CPEI target, then dont create the control file4243 */4344 if (!can_cpei_retarget() && is_cpu_cpei_target(num))4445 sysfs_cpus[num].cpu.no_control = 1;4646+#endif45474648 return register_cpu(&sysfs_cpus[num].cpu, num, parent);4749}
+34-12
arch/ia64/lib/flush.S
···33 *44 * Copyright (C) 1999-2001, 2005 Hewlett-Packard Co55 * David Mosberger-Tang <davidm@hpl.hp.com>66+ *77+ * 05/28/05 Zoltan Menyhart Dynamic stride size68 */99+710#include <asm/asmmacro.h>88-#include <asm/page.h>1111+9121013 /*1114 * flush_icache_range(start,end)1212- * Must flush range from start to end-1 but nothing else (need to1515+ *1616+ * Make i-cache(s) coherent with d-caches.1717+ *1818+ * Must deal with range from start to end-1 but nothing else (need to1319 * be careful not to touch addresses that may be unmapped).2020+ *2121+ * Note: "in0" and "in1" are preserved for debugging purposes.1422 */1523GLOBAL_ENTRY(flush_icache_range)2424+1625 .prologue1717- alloc r2=ar.pfs,2,0,0,01818- sub r8=in1,in0,12626+ alloc r2=ar.pfs,2,0,0,02727+ movl r3=ia64_i_cache_stride_shift2828+ mov r21=11929 ;;2020- shr.u r8=r8,5 // we flush 32 bytes per iteration2121- .save ar.lc, r32222- mov r3=ar.lc // save ar.lc3030+ ld8 r20=[r3] // r20: stride shift3131+ sub r22=in1,r0,1 // last byte address3232+ ;;3333+ shr.u r23=in0,r20 // start / (stride size)3434+ shr.u r22=r22,r20 // (last byte address) / (stride size)3535+ shl r21=r21,r20 // r21: stride size of the i-cache(s)3636+ ;;3737+ sub r8=r22,r23 // number of strides - 13838+ shl r24=r23,r20 // r24: addresses for "fc.i" =3939+ // "start" rounded down to stride boundary4040+ .save ar.lc,r34141+ mov r3=ar.lc // save ar.lc2342 ;;24432544 .body2626-2727- mov ar.lc=r84545+ mov ar.lc=r82846 ;;2929-.Loop: fc.i in0 // issuable on M2 only3030- add in0=32,in04747+ /*4848+ * 32 byte aligned loop, even number of (actually 2) bundles4949+ */5050+.Loop: fc.i r24 // issuable on M0 only5151+ add r24=r21,r24 // we flush "stride size" bytes per iteration5252+ nop.i 03153 br.cloop.sptk.few .Loop3254 ;;3355 sync.i3456 ;;3557 srlz.i3658 ;;3737- mov ar.lc=r3 // restore ar.lc5959+ mov ar.lc=r3 // restore ar.lc3860 br.ret.sptk.many rp3961END(flush_icache_range)
···6677extra-y := vmlinux.bin vmlinux.gz8899+# two make processes may write to vmlinux.gz at the same time with make -j1010+quiet_cmd_mygzip = GZIP $@1111+cmd_mygzip = gzip -f -9 < $< > $@.$$$$ && mv $@.$$$$ $@1212+1313+914OBJCOPYFLAGS_vmlinux.bin := -O binary1015$(obj)/vmlinux.bin: vmlinux FORCE1116 $(call if_changed,objcopy)12171318$(obj)/vmlinux.gz: $(obj)/vmlinux.bin FORCE1414- $(call if_changed,gzip)1919+ $(call if_changed,mygzip)15201621quiet_cmd_uimage = UIMAGE $@1722 cmd_uimage = $(CONFIG_SHELL) $(MKIMAGE) -A ppc -O linux -T kernel \
+21-15
arch/ppc64/kernel/cpu_setup_power4.S
···3131 */3232 mfspr r0,SPRN_PVR3333 srwi r0,r0,163434- cmpwi cr0,r0,0x393535- cmpwi cr1,r0,0x3c3636- cror 4*cr0+eq,4*cr0+eq,4*cr1+eq3434+ cmpwi r0,0x393535+ beq 1f3636+ cmpwi r0,0x3c3737+ beq 1f3838+ cmpwi r0,0x443739 bnelr4040+1:38413942 /* Make sure HID4:rm_ci is off before MMU is turned off, that large4043 * pages are enabled with HID4:61 and clear HID5:DCBZ_size and···136133 /* We only deal with 970 for now */137134 mfspr r0,SPRN_PVR138135 srwi r0,r0,16139139- cmpwi cr0,r0,0x39140140- cmpwi cr1,r0,0x3c141141- cror 4*cr0+eq,4*cr0+eq,4*cr1+eq142142- bne 1f136136+ cmpwi r0,0x39137137+ beq 1f138138+ cmpwi r0,0x3c139139+ beq 1f140140+ cmpwi r0,0x44141141+ bne 2f143142144144- /* Save HID0,1,4 and 5 */143143+1: /* Save HID0,1,4 and 5 */145144 mfspr r3,SPRN_HID0146145 std r3,CS_HID0(r5)147146 mfspr r3,SPRN_HID1···153148 mfspr r3,SPRN_HID5154149 std r3,CS_HID5(r5)155150156156-1:151151+2:157152 mtcr r7158153 blr159154···170165 /* We only deal with 970 for now */171166 mfspr r0,SPRN_PVR172167 srwi r0,r0,16173173- cmpwi cr0,r0,0x39174174- cmpwi cr1,r0,0x3c175175- cror 4*cr0+eq,4*cr0+eq,4*cr1+eq176176- bne 1f168168+ cmpwi r0,0x39169169+ beq 1f170170+ cmpwi r0,0x3c171171+ beq 1f172172+ cmpwi r0,0x44173173+ bnelr177174178178- /* Before accessing memory, we make sure rm_ci is clear */175175+1: /* Before accessing memory, we make sure rm_ci is clear */179176 li r0,0180177 mfspr r3,SPRN_HID4181178 rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */···230223 mtspr SPRN_HID5,r3231224 sync232225 isync233233-1:234226 blr235227
···3838}39394040static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,4141- unsigned long prpn, int secondary,4242- unsigned long hpteflags, int bolted, int large)4141+ unsigned long prpn, unsigned long vflags,4242+ unsigned long rflags)4343{4444 long slot;4545- HPTE lhpte;4545+ hpte_t lhpte;4646+ int secondary = 0;46474748 /*4849 * The hypervisor tries both primary and secondary.···5150 * it means we have already tried both primary and secondary,5251 * so we return failure immediately.5352 */5454- if (secondary)5353+ if (vflags & HPTE_V_SECONDARY)5554 return -1;56555756 iSeries_hlock(hpte_group);58575958 slot = HvCallHpt_findValid(&lhpte, va >> PAGE_SHIFT);6060- BUG_ON(lhpte.dw0.dw0.v);5959+ BUG_ON(lhpte.v & HPTE_V_VALID);61606261 if (slot == -1) { /* No available entry found in either group */6362 iSeries_hunlock(hpte_group);···6564 }66656766 if (slot < 0) { /* MSB set means secondary group */6767+ vflags |= HPTE_V_VALID;6868 secondary = 1;6969 slot &= 0x7fffffffffffffff;7070 }71717272- lhpte.dw1.dword1 = 0;7373- lhpte.dw1.dw1.rpn = physRpn_to_absRpn(prpn);7474- lhpte.dw1.flags.flags = hpteflags;7575-7676- lhpte.dw0.dword0 = 0;7777- lhpte.dw0.dw0.avpn = va >> 23;7878- lhpte.dw0.dw0.h = secondary;7979- lhpte.dw0.dw0.bolted = bolted;8080- lhpte.dw0.dw0.v = 1;7272+ lhpte.v = (va >> 23) << HPTE_V_AVPN_SHIFT | vflags | HPTE_V_VALID;7373+ lhpte.r = (physRpn_to_absRpn(prpn) << HPTE_R_RPN_SHIFT) | rflags;81748275 /* Now fill in the actual HPTE */8376 HvCallHpt_addValidate(slot, secondary, &lhpte);···83888489static unsigned long iSeries_hpte_getword0(unsigned long slot)8590{8686- unsigned long dword0;8787- HPTE hpte;9191+ hpte_t hpte;88928993 HvCallHpt_get(&hpte, slot);9090- dword0 = hpte.dw0.dword0;9191-9292- return dword0;9494+ return hpte.v;9395}94969597static long iSeries_hpte_remove(unsigned long hpte_group)9698{9799 unsigned long slot_offset;98100 int i;9999- HPTE lhpte;101101+ unsigned long hpte_v;100102101103 /* Pick a random slot to start at */102104 slot_offset = mftb() & 0x7;···101109 iSeries_hlock(hpte_group);102110103111 for (i = 0; i < HPTES_PER_GROUP; i++) {104104- lhpte.dw0.dword0 = 105105- iSeries_hpte_getword0(hpte_group + slot_offset);112112+ hpte_v = iSeries_hpte_getword0(hpte_group + slot_offset);106113107107- if (!lhpte.dw0.dw0.bolted) {114114+ if (! (hpte_v & HPTE_V_BOLTED)) {108115 HvCallHpt_invalidateSetSwBitsGet(hpte_group + 109116 slot_offset, 0, 0);110117 iSeries_hunlock(hpte_group);···128137static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp,129138 unsigned long va, int large, int local)130139{131131- HPTE hpte;140140+ hpte_t hpte;132141 unsigned long avpn = va >> 23;133142134143 iSeries_hlock(slot);135144136145 HvCallHpt_get(&hpte, slot);137137- if ((hpte.dw0.dw0.avpn == avpn) && (hpte.dw0.dw0.v)) {146146+ if ((HPTE_V_AVPN_VAL(hpte.v) == avpn) && (hpte.v & HPTE_V_VALID)) {138147 /*139148 * Hypervisor expects bits as NPPP, which is140149 * different from how they are mapped in our PP.···158167 */159168static long iSeries_hpte_find(unsigned long vpn)160169{161161- HPTE hpte;170170+ hpte_t hpte;162171 long slot;163172164173 /*···168177 * 0x80000000xxxxxxxx : Entry found in secondary group, slot x169178 */170179 slot = HvCallHpt_findValid(&hpte, vpn); 171171- if (hpte.dw0.dw0.v) {180180+ if (hpte.v & HPTE_V_VALID) {172181 if (slot < 0) {173182 slot &= 0x7fffffffffffffff;174183 slot = -slot;···203212static void iSeries_hpte_invalidate(unsigned long slot, unsigned long va,204213 int large, int local)205214{206206- HPTE lhpte;215215+ unsigned long hpte_v;207216 unsigned long avpn = va >> 23;208217 unsigned long flags;209218···211220212221 iSeries_hlock(slot);213222214214- lhpte.dw0.dword0 = iSeries_hpte_getword0(slot);223223+ hpte_v = iSeries_hpte_getword0(slot);215224216216- if ((lhpte.dw0.dw0.avpn == avpn) && lhpte.dw0.dw0.v)225225+ if ((HPTE_V_AVPN_VAL(hpte_v) == avpn) && (hpte_v & HPTE_V_VALID))217226 HvCallHpt_invalidateSetSwBitsGet(slot, 0, 0);218227219228 iSeries_hunlock(slot);
+8-10
arch/ppc64/kernel/iSeries_setup.c
···503503504504 /* Fill in the hashed page table hash mask */505505 num_ptegs = hptSizePages *506506- (PAGE_SIZE / (sizeof(HPTE) * HPTES_PER_GROUP));506506+ (PAGE_SIZE / (sizeof(hpte_t) * HPTES_PER_GROUP));507507 htab_hash_mask = num_ptegs - 1;508508509509 /*···618618static void iSeries_make_pte(unsigned long va, unsigned long pa,619619 int mode)620620{621621- HPTE local_hpte, rhpte;621621+ hpte_t local_hpte, rhpte;622622 unsigned long hash, vpn;623623 long slot;624624625625 vpn = va >> PAGE_SHIFT;626626 hash = hpt_hash(vpn, 0);627627628628- local_hpte.dw1.dword1 = pa | mode;629629- local_hpte.dw0.dword0 = 0;630630- local_hpte.dw0.dw0.avpn = va >> 23;631631- local_hpte.dw0.dw0.bolted = 1; /* bolted */632632- local_hpte.dw0.dw0.v = 1;628628+ local_hpte.r = pa | mode;629629+ local_hpte.v = ((va >> 23) << HPTE_V_AVPN_SHIFT)630630+ | HPTE_V_BOLTED | HPTE_V_VALID;633631634632 slot = HvCallHpt_findValid(&rhpte, vpn);635633 if (slot < 0) {636634 /* Must find space in primary group */637635 panic("hash_page: hpte already exists\n");638636 }639639- HvCallHpt_addValidate(slot, 0, (HPTE *)&local_hpte );637637+ HvCallHpt_addValidate(slot, 0, &local_hpte);640638}641639642640/*···644646{645647 unsigned long pa;646648 unsigned long mode_rw = _PAGE_ACCESSED | _PAGE_COHERENT | PP_RWXX;647647- HPTE hpte;649649+ hpte_t hpte;648650649651 for (pa = saddr; pa < eaddr ;pa += PAGE_SIZE) {650652 unsigned long ea = (unsigned long)__va(pa);···657659 if (!in_kernel_text(ea))658660 mode_rw |= HW_NO_EXEC;659661660660- if (hpte.dw0.dw0.v) {662662+ if (hpte.v & HPTE_V_VALID) {661663 /* HPTE exists, so just bolt it */662664 HvCallHpt_setSwBits(slot, 0x10, 0);663665 /* And make sure the pp bits are correct */
+16-31
arch/ppc64/kernel/pSeries_lpar.c
···277277278278long pSeries_lpar_hpte_insert(unsigned long hpte_group,279279 unsigned long va, unsigned long prpn,280280- int secondary, unsigned long hpteflags,281281- int bolted, int large)280280+ unsigned long vflags, unsigned long rflags)282281{283282 unsigned long arpn = physRpn_to_absRpn(prpn);284283 unsigned long lpar_rc;285284 unsigned long flags;286285 unsigned long slot;287287- HPTE lhpte;286286+ unsigned long hpte_v, hpte_r;288287 unsigned long dummy0, dummy1;289288290290- /* Fill in the local HPTE with absolute rpn, avpn and flags */291291- lhpte.dw1.dword1 = 0;292292- lhpte.dw1.dw1.rpn = arpn;293293- lhpte.dw1.flags.flags = hpteflags;289289+ hpte_v = ((va >> 23) << HPTE_V_AVPN_SHIFT) | vflags | HPTE_V_VALID;290290+ if (vflags & HPTE_V_LARGE)291291+ hpte_v &= ~(1UL << HPTE_V_AVPN_SHIFT);294292295295- lhpte.dw0.dword0 = 0;296296- lhpte.dw0.dw0.avpn = va >> 23;297297- lhpte.dw0.dw0.h = secondary;298298- lhpte.dw0.dw0.bolted = bolted;299299- lhpte.dw0.dw0.v = 1;300300-301301- if (large) {302302- lhpte.dw0.dw0.l = 1;303303- lhpte.dw0.dw0.avpn &= ~0x1UL;304304- }293293+ hpte_r = (arpn << HPTE_R_RPN_SHIFT) | rflags;305294306295 /* Now fill in the actual HPTE */307296 /* Set CEC cookie to 0 */···301312 flags = 0;302313303314 /* XXX why is this here? - Anton */304304- if (hpteflags & (_PAGE_GUARDED|_PAGE_NO_CACHE))305305- lhpte.dw1.flags.flags &= ~_PAGE_COHERENT;315315+ if (rflags & (_PAGE_GUARDED|_PAGE_NO_CACHE))316316+ hpte_r &= ~_PAGE_COHERENT;306317307307- lpar_rc = plpar_hcall(H_ENTER, flags, hpte_group, lhpte.dw0.dword0,308308- lhpte.dw1.dword1, &slot, &dummy0, &dummy1);318318+ lpar_rc = plpar_hcall(H_ENTER, flags, hpte_group, hpte_v,319319+ hpte_r, &slot, &dummy0, &dummy1);309320310321 if (unlikely(lpar_rc == H_PTEG_Full))311322 return -1;···321332 /* Because of iSeries, we have to pass down the secondary322333 * bucket bit here as well323334 */324324- return (slot & 7) | (secondary << 3);335335+ return (slot & 7) | (!!(vflags & HPTE_V_SECONDARY) << 3);325336}326337327338static DEFINE_SPINLOCK(pSeries_lpar_tlbie_lock);···416427 unsigned long hash;417428 unsigned long i, j;418429 long slot;419419- union {420420- unsigned long dword0;421421- Hpte_dword0 dw0;422422- } hpte_dw0;423423- Hpte_dword0 dw0;430430+ unsigned long hpte_v;424431425432 hash = hpt_hash(vpn, 0);426433427434 for (j = 0; j < 2; j++) {428435 slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;429436 for (i = 0; i < HPTES_PER_GROUP; i++) {430430- hpte_dw0.dword0 = pSeries_lpar_hpte_getword0(slot);431431- dw0 = hpte_dw0.dw0;437437+ hpte_v = pSeries_lpar_hpte_getword0(slot);432438433433- if ((dw0.avpn == (vpn >> 11)) && dw0.v &&434434- (dw0.h == j)) {439439+ if ((HPTE_V_AVPN_VAL(hpte_v) == (vpn >> 11))440440+ && (hpte_v & HPTE_V_VALID)441441+ && (!!(hpte_v & HPTE_V_SECONDARY) == j)) {435442 /* HPTE matches */436443 if (j)437444 slot = -slot;
+2-6
arch/ppc64/mm/hash_low.S
···170170 /* Call ppc_md.hpte_insert */171171 ld r7,STK_PARM(r4)(r1) /* Retreive new pp bits */172172 mr r4,r29 /* Retreive va */173173- li r6,0 /* primary slot */174174- li r8,0 /* not bolted and not large */175175- li r9,0173173+ li r6,0 /* no vflags */176174_GLOBAL(htab_call_hpte_insert1)177175 bl . /* Will be patched by htab_finish_init() */178176 cmpdi 0,r3,0···190192 /* Call ppc_md.hpte_insert */191193 ld r7,STK_PARM(r4)(r1) /* Retreive new pp bits */192194 mr r4,r29 /* Retreive va */193193- li r6,1 /* secondary slot */194194- li r8,0 /* not bolted and not large */195195- li r9,0195195+ li r6,HPTE_V_SECONDARY@l /* secondary slot */196196_GLOBAL(htab_call_hpte_insert2)197197 bl . /* Will be patched by htab_finish_init() */198198 cmpdi 0,r3,0
+59-70
arch/ppc64/mm/hash_native.c
···27272828static DEFINE_SPINLOCK(native_tlbie_lock);29293030-static inline void native_lock_hpte(HPTE *hptep)3030+static inline void native_lock_hpte(hpte_t *hptep)3131{3232- unsigned long *word = &hptep->dw0.dword0;3232+ unsigned long *word = &hptep->v;33333434 while (1) {3535 if (!test_and_set_bit(HPTE_LOCK_BIT, word))···3939 }4040}41414242-static inline void native_unlock_hpte(HPTE *hptep)4242+static inline void native_unlock_hpte(hpte_t *hptep)4343{4444- unsigned long *word = &hptep->dw0.dword0;4444+ unsigned long *word = &hptep->v;45454646 asm volatile("lwsync":::"memory");4747 clear_bit(HPTE_LOCK_BIT, word);4848}49495050long native_hpte_insert(unsigned long hpte_group, unsigned long va,5151- unsigned long prpn, int secondary,5252- unsigned long hpteflags, int bolted, int large)5151+ unsigned long prpn, unsigned long vflags,5252+ unsigned long rflags)5353{5454 unsigned long arpn = physRpn_to_absRpn(prpn);5555- HPTE *hptep = htab_address + hpte_group;5656- Hpte_dword0 dw0;5757- HPTE lhpte;5555+ hpte_t *hptep = htab_address + hpte_group;5656+ unsigned long hpte_v, hpte_r;5857 int i;59586059 for (i = 0; i < HPTES_PER_GROUP; i++) {6161- dw0 = hptep->dw0.dw0;6262-6363- if (!dw0.v) {6060+ if (! (hptep->v & HPTE_V_VALID)) {6461 /* retry with lock held */6562 native_lock_hpte(hptep);6666- dw0 = hptep->dw0.dw0;6767- if (!dw0.v)6363+ if (! (hptep->v & HPTE_V_VALID))6864 break;6965 native_unlock_hpte(hptep);7066 }···7175 if (i == HPTES_PER_GROUP)7276 return -1;73777474- lhpte.dw1.dword1 = 0;7575- lhpte.dw1.dw1.rpn = arpn;7676- lhpte.dw1.flags.flags = hpteflags;7878+ hpte_v = (va >> 23) << HPTE_V_AVPN_SHIFT | vflags | HPTE_V_VALID;7979+ if (vflags & HPTE_V_LARGE)8080+ va &= ~(1UL << HPTE_V_AVPN_SHIFT);8181+ hpte_r = (arpn << HPTE_R_RPN_SHIFT) | rflags;77827878- lhpte.dw0.dword0 = 0;7979- lhpte.dw0.dw0.avpn = va >> 23;8080- lhpte.dw0.dw0.h = secondary;8181- lhpte.dw0.dw0.bolted = bolted;8282- lhpte.dw0.dw0.v = 1;8383-8484- if (large) {8585- lhpte.dw0.dw0.l = 1;8686- lhpte.dw0.dw0.avpn &= ~0x1UL;8787- }8888-8989- hptep->dw1.dword1 = lhpte.dw1.dword1;9090-8383+ hptep->r = hpte_r;9184 /* Guarantee the second dword is visible before the valid bit */9285 __asm__ __volatile__ ("eieio" : : : "memory");9393-9486 /*9587 * Now set the first dword including the valid bit9688 * NOTE: this also unlocks the hpte9789 */9898- hptep->dw0.dword0 = lhpte.dw0.dword0;9090+ hptep->v = hpte_v;999110092 __asm__ __volatile__ ("ptesync" : : : "memory");10193102102- return i | (secondary << 3);9494+ return i | (!!(vflags & HPTE_V_SECONDARY) << 3);10395}1049610597static long native_hpte_remove(unsigned long hpte_group)10698{107107- HPTE *hptep;108108- Hpte_dword0 dw0;9999+ hpte_t *hptep;109100 int i;110101 int slot_offset;102102+ unsigned long hpte_v;111103112104 /* pick a random entry to start at */113105 slot_offset = mftb() & 0x7;114106115107 for (i = 0; i < HPTES_PER_GROUP; i++) {116108 hptep = htab_address + hpte_group + slot_offset;117117- dw0 = hptep->dw0.dw0;109109+ hpte_v = hptep->v;118110119119- if (dw0.v && !dw0.bolted) {111111+ if ((hpte_v & HPTE_V_VALID) && !(hpte_v & HPTE_V_BOLTED)) {120112 /* retry with lock held */121113 native_lock_hpte(hptep);122122- dw0 = hptep->dw0.dw0;123123- if (dw0.v && !dw0.bolted)114114+ hpte_v = hptep->v;115115+ if ((hpte_v & HPTE_V_VALID)116116+ && !(hpte_v & HPTE_V_BOLTED))124117 break;125118 native_unlock_hpte(hptep);126119 }···122137 return -1;123138124139 /* Invalidate the hpte. NOTE: this also unlocks it */125125- hptep->dw0.dword0 = 0;140140+ hptep->v = 0;126141127142 return i;128143}129144130130-static inline void set_pp_bit(unsigned long pp, HPTE *addr)145145+static inline void set_pp_bit(unsigned long pp, hpte_t *addr)131146{132147 unsigned long old;133133- unsigned long *p = &addr->dw1.dword1;148148+ unsigned long *p = &addr->r;134149135150 __asm__ __volatile__(136151 "1: ldarx %0,0,%3\n\···148163 */149164static long native_hpte_find(unsigned long vpn)150165{151151- HPTE *hptep;166166+ hpte_t *hptep;152167 unsigned long hash;153168 unsigned long i, j;154169 long slot;155155- Hpte_dword0 dw0;170170+ unsigned long hpte_v;156171157172 hash = hpt_hash(vpn, 0);158173···160175 slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;161176 for (i = 0; i < HPTES_PER_GROUP; i++) {162177 hptep = htab_address + slot;163163- dw0 = hptep->dw0.dw0;178178+ hpte_v = hptep->v;164179165165- if ((dw0.avpn == (vpn >> 11)) && dw0.v &&166166- (dw0.h == j)) {180180+ if ((HPTE_V_AVPN_VAL(hpte_v) == (vpn >> 11))181181+ && (hpte_v & HPTE_V_VALID)182182+ && ( !!(hpte_v & HPTE_V_SECONDARY) == j)) {167183 /* HPTE matches */168184 if (j)169185 slot = -slot;···181195static long native_hpte_updatepp(unsigned long slot, unsigned long newpp,182196 unsigned long va, int large, int local)183197{184184- HPTE *hptep = htab_address + slot;185185- Hpte_dword0 dw0;198198+ hpte_t *hptep = htab_address + slot;199199+ unsigned long hpte_v;186200 unsigned long avpn = va >> 23;187201 int ret = 0;188202189203 if (large)190190- avpn &= ~0x1UL;204204+ avpn &= ~1;191205192206 native_lock_hpte(hptep);193207194194- dw0 = hptep->dw0.dw0;208208+ hpte_v = hptep->v;195209196210 /* Even if we miss, we need to invalidate the TLB */197197- if ((dw0.avpn != avpn) || !dw0.v) {211211+ if ((HPTE_V_AVPN_VAL(hpte_v) != avpn)212212+ || !(hpte_v & HPTE_V_VALID)) {198213 native_unlock_hpte(hptep);199214 ret = -1;200215 } else {···231244{232245 unsigned long vsid, va, vpn, flags = 0;233246 long slot;234234- HPTE *hptep;247247+ hpte_t *hptep;235248 int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);236249237250 vsid = get_kernel_vsid(ea);···256269static void native_hpte_invalidate(unsigned long slot, unsigned long va,257270 int large, int local)258271{259259- HPTE *hptep = htab_address + slot;260260- Hpte_dword0 dw0;272272+ hpte_t *hptep = htab_address + slot;273273+ unsigned long hpte_v;261274 unsigned long avpn = va >> 23;262275 unsigned long flags;263276 int lock_tlbie = !cpu_has_feature(CPU_FTR_LOCKLESS_TLBIE);264277265278 if (large)266266- avpn &= ~0x1UL;279279+ avpn &= ~1;267280268281 local_irq_save(flags);269282 native_lock_hpte(hptep);270283271271- dw0 = hptep->dw0.dw0;284284+ hpte_v = hptep->v;272285273286 /* Even if we miss, we need to invalidate the TLB */274274- if ((dw0.avpn != avpn) || !dw0.v) {287287+ if ((HPTE_V_AVPN_VAL(hpte_v) != avpn)288288+ || !(hpte_v & HPTE_V_VALID)) {275289 native_unlock_hpte(hptep);276290 } else {277291 /* Invalidate the hpte. NOTE: this also unlocks it */278278- hptep->dw0.dword0 = 0;292292+ hptep->v = 0;279293 }280294281295 /* Invalidate the tlb */···303315static void native_hpte_clear(void)304316{305317 unsigned long slot, slots, flags;306306- HPTE *hptep = htab_address;307307- Hpte_dword0 dw0;318318+ hpte_t *hptep = htab_address;319319+ unsigned long hpte_v;308320 unsigned long pteg_count;309321310322 pteg_count = htab_hash_mask + 1;···324336 * running, right? and for crash dump, we probably325337 * don't want to wait for a maybe bad cpu.326338 */327327- dw0 = hptep->dw0.dw0;339339+ hpte_v = hptep->v;328340329329- if (dw0.v) {330330- hptep->dw0.dword0 = 0;331331- tlbie(slot2va(dw0.avpn, dw0.l, dw0.h, slot), dw0.l);341341+ if (hpte_v & HPTE_V_VALID) {342342+ hptep->v = 0;343343+ tlbie(slot2va(hpte_v, slot), hpte_v & HPTE_V_LARGE);332344 }333345 }334346···341353{342354 unsigned long vsid, vpn, va, hash, secondary, slot, flags, avpn;343355 int i, j;344344- HPTE *hptep;345345- Hpte_dword0 dw0;356356+ hpte_t *hptep;357357+ unsigned long hpte_v;346358 struct ppc64_tlb_batch *batch = &__get_cpu_var(ppc64_tlb_batch);347359348360 /* XXX fix for large ptes */···378390379391 native_lock_hpte(hptep);380392381381- dw0 = hptep->dw0.dw0;393393+ hpte_v = hptep->v;382394383395 /* Even if we miss, we need to invalidate the TLB */384384- if ((dw0.avpn != avpn) || !dw0.v) {396396+ if ((HPTE_V_AVPN_VAL(hpte_v) != avpn)397397+ || !(hpte_v & HPTE_V_VALID)) {385398 native_unlock_hpte(hptep);386399 } else {387400 /* Invalidate the hpte. NOTE: this also unlocks it */388388- hptep->dw0.dword0 = 0;401401+ hptep->v = 0;389402 }390403391404 j++;
+10-6
arch/ppc64/mm/hash_utils.c
···7575extern unsigned long dart_tablebase;7676#endif /* CONFIG_U3_DART */77777878-HPTE *htab_address;7979-unsigned long htab_hash_mask;7878+hpte_t *htab_address;7979+unsigned long htab_hash_mask;80808181extern unsigned long _SDR1;8282···9797 unsigned long addr;9898 unsigned int step;9999 unsigned long tmp_mode;100100+ unsigned long vflags;100101101101- if (large)102102+ if (large) {102103 step = 16*MB;103103- else104104+ vflags = HPTE_V_BOLTED | HPTE_V_LARGE;105105+ } else {104106 step = 4*KB;107107+ vflags = HPTE_V_BOLTED;108108+ }105109106110 for (addr = start; addr < end; addr += step) {107111 unsigned long vpn, hash, hpteg;···133129 if (systemcfg->platform & PLATFORM_LPAR)134130 ret = pSeries_lpar_hpte_insert(hpteg, va,135131 virt_to_abs(addr) >> PAGE_SHIFT,136136- 0, tmp_mode, 1, large);132132+ vflags, tmp_mode);137133 else138134#endif /* CONFIG_PPC_PSERIES */139135 ret = native_hpte_insert(hpteg, va,140136 virt_to_abs(addr) >> PAGE_SHIFT,141141- 0, tmp_mode, 1, large);137137+ vflags, tmp_mode);142138143139 if (ret == -1) {144140 ppc64_terminate_msg(0x20, "create_pte_mapping");
+8-8
arch/ppc64/mm/hugetlbpage.c
···583583 pte_t *ptep;584584 unsigned long va, vpn;585585 pte_t old_pte, new_pte;586586- unsigned long hpteflags, prpn;586586+ unsigned long rflags, prpn;587587 long slot;588588 int err = 1;589589···626626 old_pte = *ptep;627627 new_pte = old_pte;628628629629- hpteflags = 0x2 | (! (pte_val(new_pte) & _PAGE_RW));629629+ rflags = 0x2 | (! (pte_val(new_pte) & _PAGE_RW));630630 /* _PAGE_EXEC -> HW_NO_EXEC since it's inverted */631631- hpteflags |= ((pte_val(new_pte) & _PAGE_EXEC) ? 0 : HW_NO_EXEC);631631+ rflags |= ((pte_val(new_pte) & _PAGE_EXEC) ? 0 : HW_NO_EXEC);632632633633 /* Check if pte already has an hpte (case 2) */634634 if (unlikely(pte_val(old_pte) & _PAGE_HASHPTE)) {···641641 slot = (hash & htab_hash_mask) * HPTES_PER_GROUP;642642 slot += (pte_val(old_pte) & _PAGE_GROUP_IX) >> 12;643643644644- if (ppc_md.hpte_updatepp(slot, hpteflags, va, 1, local) == -1)644644+ if (ppc_md.hpte_updatepp(slot, rflags, va, 1, local) == -1)645645 pte_val(old_pte) &= ~_PAGE_HPTEFLAGS;646646 }647647···661661662662 /* Add in WIMG bits */663663 /* XXX We should store these in the pte */664664- hpteflags |= _PAGE_COHERENT;664664+ rflags |= _PAGE_COHERENT;665665666666- slot = ppc_md.hpte_insert(hpte_group, va, prpn, 0,667667- hpteflags, 0, 1);666666+ slot = ppc_md.hpte_insert(hpte_group, va, prpn,667667+ HPTE_V_LARGE, rflags);668668669669 /* Primary is full, try the secondary */670670 if (unlikely(slot == -1)) {···672672 hpte_group = ((~hash & htab_hash_mask) *673673 HPTES_PER_GROUP) & ~0x7UL; 674674 slot = ppc_md.hpte_insert(hpte_group, va, prpn,675675- 1, hpteflags, 0, 1);675675+ HPTE_V_LARGE, rflags);676676 if (slot == -1) {677677 if (mftb() & 0x1)678678 hpte_group = ((hash & htab_hash_mask) * HPTES_PER_GROUP) & ~0x7UL;
+4-3
arch/ppc64/mm/init.c
···180180 hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP);181181182182 /* Panic if a pte grpup is full */183183- if (ppc_md.hpte_insert(hpteg, va, pa >> PAGE_SHIFT, 0,184184- _PAGE_NO_CACHE|_PAGE_GUARDED|PP_RWXX,185185- 1, 0) == -1) {183183+ if (ppc_md.hpte_insert(hpteg, va, pa >> PAGE_SHIFT,184184+ HPTE_V_BOLTED,185185+ _PAGE_NO_CACHE|_PAGE_GUARDED|PP_RWXX)186186+ == -1) {186187 panic("map_io_page: could not insert mapping");187188 }188189 }
+38
arch/s390/kernel/compat_linux.c
···5858#include <linux/compat.h>5959#include <linux/vfs.h>6060#include <linux/ptrace.h>6161+#include <linux/fadvise.h>61626263#include <asm/types.h>6364#include <asm/ipc.h>···10431042 ret = put_user (ktimer_id, timer_id);1044104310451044 return ret;10451045+}10461046+10471047+/*10481048+ * 31 bit emulation wrapper functions for sys_fadvise64/fadvise64_64.10491049+ * These need to rewrite the advise values for POSIX_FADV_{DONTNEED,NOREUSE}10501050+ * because the 31 bit values differ from the 64 bit values.10511051+ */10521052+10531053+asmlinkage long10541054+sys32_fadvise64(int fd, loff_t offset, size_t len, int advise)10551055+{10561056+ if (advise == 4)10571057+ advise = POSIX_FADV_DONTNEED;10581058+ else if (advise == 5)10591059+ advise = POSIX_FADV_NOREUSE;10601060+ return sys_fadvise64(fd, offset, len, advise);10611061+}10621062+10631063+struct fadvise64_64_args {10641064+ int fd;10651065+ long long offset;10661066+ long long len;10671067+ int advice;10681068+};10691069+10701070+asmlinkage long10711071+sys32_fadvise64_64(struct fadvise64_64_args __user *args)10721072+{10731073+ struct fadvise64_64_args a;10741074+10751075+ if ( copy_from_user(&a, args, sizeof(a)) )10761076+ return -EFAULT;10771077+ if (a.advice == 4)10781078+ a.advice = POSIX_FADV_DONTNEED;10791079+ else if (a.advice == 5)10801080+ a.advice = POSIX_FADV_NOREUSE;10811081+ return sys_fadvise64_64(a.fd, a.offset, a.len, a.advice);10461082}
+2-2
arch/s390/kernel/compat_wrapper.S
···12511251 or %r3,%r4 # get low word of 64bit loff_t12521252 llgfr %r4,%r5 # size_t (unsigned long)12531253 lgfr %r5,%r6 # int12541254- jg sys_fadvise6412541254+ jg sys32_fadvise641255125512561256 .globl sys32_fadvise64_64_wrapper12571257sys32_fadvise64_64_wrapper:12581258 llgtr %r2,%r2 # struct fadvise64_64_args *12591259- jg s390_fadvise64_6412591259+ jg sys32_fadvise64_641260126012611261 .globl sys32_clock_settime_wrapper12621262sys32_clock_settime_wrapper:
+1-1
arch/um/Kconfig_net
···135135136136config UML_NET_PCAP137137 bool "pcap transport"138138- depends on UML_NET && BROKEN138138+ depends on UML_NET && EXPERIMENTAL139139 help140140 The pcap transport makes a pcap packet stream on the host look141141 like an ethernet device inside UML. This is useful for making
+16-14
arch/um/Makefile
···5151endif5252SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH)53535454-include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)5454+# -Dvmap=kernel_vmap affects everything, and prevents anything from5555+# referencing the libpcap.o symbol so named.55565656-core-y += $(SUBARCH_CORE)5757-libs-y += $(SUBARCH_LIBS)5757+CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \5858+ $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap5959+6060+USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))6161+USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \6262+ $(MODE_INCLUDE)58635964# -Derrno=kernel_errno - This turns all kernel references to errno into6065# kernel_errno to separate them from the libc errno. This allows -fno-common6166# in CFLAGS. Otherwise, it would cause ld to complain about the two different6267# errnos.63686464-CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \6565- $(ARCH_INCLUDE) $(MODE_INCLUDE)6666-6767-USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))6868-USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \6969- $(MODE_INCLUDE) $(ARCH_USER_CFLAGS)7069CFLAGS += -Derrno=kernel_errno -Dsigprocmask=kernel_sigprocmask7170CFLAGS += $(call cc-option,-fno-unit-at-a-time,)7171+7272+include $(srctree)/$(ARCH_DIR)/Makefile-$(SUBARCH)72737374#This will adjust *FLAGS accordingly to the platform.7475include $(srctree)/$(ARCH_DIR)/Makefile-os-$(OS)···117116STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )118117119118ifndef START120120- START = $$(($(TOP_ADDR) - $(SIZE)))119119+ START = $(shell echo $$[ $(TOP_ADDR) - $(SIZE) ] )121120endif122121123123-CPPFLAGS_vmlinux.lds = $(shell echo -U$(SUBARCH) \122122+CPPFLAGS_vmlinux.lds = -U$(SUBARCH) \124123 -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \125125- -DELF_FORMAT=\"$(ELF_FORMAT)\" $(CPP_MODE-y) \126126- -DKERNEL_STACK_SIZE=$(STACK_SIZE) -DSUBARCH=$(SUBARCH))124124+ -DELF_FORMAT="$(ELF_FORMAT)" $(CPP_MODE-y) \125125+ -DKERNEL_STACK_SIZE=$(STACK_SIZE) \126126+ -DUNMAP_PATH=arch/um/sys-$(SUBARCH)/unmap_fin.o127127128128#The wrappers will select whether using "malloc" or the kernel allocator.129129LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc130130131131-CFLAGS_vmlinux = $(LINK-y) $(LINK_WRAPS)131131+CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS)132132define cmd_vmlinux__133133 $(CC) $(CFLAGS_vmlinux) -o $@ \134134 -Wl,-T,$(vmlinux-lds) $(vmlinux-init) \
···44 */5566#include "linux/config.h"77+#include "linux/sched.h"78#include "linux/slab.h"99+#include "linux/types.h"810#include "asm/uaccess.h"911#include "asm/ptrace.h"1212+#include "asm/smp.h"1313+#include "asm/ldt.h"1014#include "choose-mode.h"1115#include "kern.h"1616+#include "mode_kern.h"12171318#ifdef CONFIG_MODE_TT1919+1420extern int modify_ldt(int func, void *ptr, unsigned long bytecount);15211616-/* XXX this needs copy_to_user and copy_from_user */1717-1818-int sys_modify_ldt_tt(int func, void __user *ptr, unsigned long bytecount)2222+static int do_modify_ldt_tt(int func, void *ptr, unsigned long bytecount)1923{2020- if (!access_ok(VERIFY_READ, ptr, bytecount))2121- return -EFAULT;2222-2324 return modify_ldt(func, ptr, bytecount);2425}2626+2527#endif26282729#ifdef CONFIG_MODE_SKAS2828-extern int userspace_pid[];29303131+#include "skas.h"3032#include "skas_ptrace.h"31333232-int sys_modify_ldt_skas(int func, void __user *ptr, unsigned long bytecount)3434+static int do_modify_ldt_skas(int func, void *ptr, unsigned long bytecount)3335{3436 struct ptrace_ldt ldt;3535- void *buf;3636- int res, n;3737+ u32 cpu;3838+ int res;37393838- buf = kmalloc(bytecount, GFP_KERNEL);3939- if(buf == NULL)4040- return(-ENOMEM);4040+ ldt = ((struct ptrace_ldt) { .func = func,4141+ .ptr = ptr,4242+ .bytecount = bytecount });41434242- res = 0;4444+ cpu = get_cpu();4545+ res = ptrace(PTRACE_LDT, userspace_pid[cpu], 0, (unsigned long) &ldt);4646+ put_cpu();4747+4848+ return res;4949+}5050+#endif5151+5252+int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)5353+{5454+ struct user_desc info;5555+ int res = 0;5656+ void *buf = NULL;5757+ void *p = NULL; /* What we pass to host. */43584459 switch(func){4560 case 1:4646- case 0x11:4747- res = copy_from_user(buf, ptr, bytecount);4848- break;4949- }6161+ case 0x11: /* write_ldt */6262+ /* Do this check now to avoid overflows. */6363+ if (bytecount != sizeof(struct user_desc)) {6464+ res = -EINVAL;6565+ goto out;6666+ }50675151- if(res != 0){5252- res = -EFAULT;6868+ if(copy_from_user(&info, ptr, sizeof(info))) {6969+ res = -EFAULT;7070+ goto out;7171+ }7272+7373+ p = &info;7474+ break;7575+ case 0:7676+ case 2: /* read_ldt */7777+7878+ /* The use of info avoids kmalloc on the write case, not on the7979+ * read one. */8080+ buf = kmalloc(bytecount, GFP_KERNEL);8181+ if (!buf) {8282+ res = -ENOMEM;8383+ goto out;8484+ }8585+ p = buf;8686+ default:8787+ res = -ENOSYS;5388 goto out;5489 }55905656- ldt = ((struct ptrace_ldt) { .func = func,5757- .ptr = buf,5858- .bytecount = bytecount });5959-#warning Need to look up userspace_pid by cpu6060- res = ptrace(PTRACE_LDT, userspace_pid[0], 0, (unsigned long) &ldt);9191+ res = CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func,9292+ p, bytecount);6193 if(res < 0)6294 goto out;63956496 switch(func){6597 case 0:6698 case 2:6767- n = res;6868- res = copy_to_user(ptr, buf, n);6969- if(res != 0)9999+ /* Modify_ldt was for reading and returned the number of read100100+ * bytes.*/101101+ if(copy_to_user(ptr, p, res))70102 res = -EFAULT;7171- else 7272- res = n;73103 break;74104 }751057676- out:106106+out:77107 kfree(buf);7878- return(res);108108+ return res;79109}8080-#endif8181-8282-int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)8383-{8484- return(CHOOSE_MODE_PROC(sys_modify_ldt_tt, sys_modify_ldt_skas, func, 8585- ptr, bytecount));8686-}8787-8888-8989-9090-/*9191- * Overrides for Emacs so that we follow Linus's tabbing style.9292- * Emacs will notice this stuff at the end of the file and automatically9393- * adjust the settings for this buffer only. This must remain at the end9494- * of the file.9595- * ---------------------------------------------------------------------------9696- * Local variables:9797- * c-file-style: "linux"9898- * End:9999- */
···11/*22 * arch/v850/vmlinux.lds.S -- kernel linker script for v850 platforms33 *44- * Copyright (C) 2002,03,04 NEC Electronics Corporation55- * Copyright (C) 2002,03,04 Miles Bader <miles@gnu.org>44+ * Copyright (C) 2002,03,04,05 NEC Electronics Corporation55+ * Copyright (C) 2002,03,04,05 Miles Bader <miles@gnu.org>66 *77 * This file is subject to the terms and conditions of the GNU General88 * Public License. See the file COPYING in the main directory of this···6161 *(__kcrctab_gpl) \6262 ___stop___kcrctab_gpl = .; \6363 /* Built-in module parameters */ \6464+ . = ALIGN (4) ; \6465 ___start___param = .; \6566 *(__param) \6667 ___stop___param = .;
···355355 ToRecv = space;356356357357 if (ToRecv <= 0)358358- return;358358+ goto done;359359360360 /*361361 * if status indicates there are errored characters in the···437437 }438438 /* Push the data up to the tty layer */439439 ld->receive_buf(tty, tty->flip.char_buf, tty->flip.flag_buf, count);440440+done:440441 tty_ldisc_deref(ld);441442}442443
···13451345 }13461346}1347134713481348-int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks)13481348+int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks,13491349+ int degraded)13491350{13501351 bitmap_counter_t *bmc;13511352 int rv;···13631362 rv = 1;13641363 else if (NEEDED(*bmc)) {13651364 rv = 1;13661366- *bmc |= RESYNC_MASK;13671367- *bmc &= ~NEEDED_MASK;13651365+ if (!degraded) { /* don't set/clear bits if degraded */13661366+ *bmc |= RESYNC_MASK;13671367+ *bmc &= ~NEEDED_MASK;13681368+ }13681369 }13691370 }13701371 spin_unlock_irq(&bitmap->lock);
+4-4
drivers/md/raid0.c
···314314 sector_t space = conf->hash_spacing;315315 int round;316316 conf->preshift = 0;317317- if (sizeof(sector_t) > sizeof(unsigned long)) {317317+ if (sizeof(sector_t) > sizeof(u32)) {318318 /*shift down space and s so that sector_div will work */319319- while (space > (sector_t) (~(unsigned long)0)) {319319+ while (space > (sector_t) (~(u32)0)) {320320 s >>= 1;321321 space >>= 1;322322 s += 1; /* force round-up */323323 conf->preshift++;324324 }325325 }326326- round = sector_div(s, (unsigned long)space) ? 1 : 0;326326+ round = sector_div(s, (u32)space) ? 1 : 0;327327 nb_zone = s + round;328328 }329329 printk("raid0 : nb_zone is %d.\n", nb_zone);···443443 volatile444444#endif445445 sector_t x = block >> conf->preshift;446446- sector_div(x, (unsigned long)conf->hash_spacing);446446+ sector_div(x, (u32)conf->hash_spacing);447447 zone = conf->hash_table[x];448448 }449449
+18-19
drivers/md/raid1.c
···11261126 * only be one in raid1 resync.11271127 * We can find the current addess in mddev->curr_resync11281128 */11291129- if (!conf->fullsync) {11301130- if (mddev->curr_resync < max_sector)11311131- bitmap_end_sync(mddev->bitmap,11321132- mddev->curr_resync,11291129+ if (mddev->curr_resync < max_sector) /* aborted */11301130+ bitmap_end_sync(mddev->bitmap, mddev->curr_resync,11331131 &sync_blocks, 1);11341134- bitmap_close_sync(mddev->bitmap);11351135- }11361136- if (mddev->curr_resync >= max_sector)11321132+ else /* completed sync */11371133 conf->fullsync = 0;11341134+11351135+ bitmap_close_sync(mddev->bitmap);11381136 close_sync(conf);11391137 return 0;11401138 }1141113911421142- if (!conf->fullsync &&11431143- !bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks)) {11401140+ if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, mddev->degraded) &&11411141+ !conf->fullsync) {11441142 /* We can skip this block, and probably several more */11451143 *skipped = 1;11461144 return sync_blocks;···12411243 len = (max_sector - sector_nr) << 9;12421244 if (len == 0)12431245 break;12441244- if (!conf->fullsync) {12451245- if (sync_blocks == 0) {12461246- if (!bitmap_start_sync(mddev->bitmap,12471247- sector_nr, &sync_blocks))12481248- break;12491249- if (sync_blocks < (PAGE_SIZE>>9))12501250- BUG();12511251- if (len > (sync_blocks<<9)) len = sync_blocks<<9;12521252- }12461246+ if (sync_blocks == 0) {12471247+ if (!bitmap_start_sync(mddev->bitmap, sector_nr,12481248+ &sync_blocks, mddev->degraded) &&12491249+ !conf->fullsync)12501250+ break;12511251+ if (sync_blocks < (PAGE_SIZE>>9))12521252+ BUG();12531253+ if (len > (sync_blocks<<9))12541254+ len = sync_blocks<<9;12531255 }1254125612551257 for (i=0 ; i < conf->raid_disks; i++) {···12621264 while (i > 0) {12631265 i--;12641266 bio = r1_bio->bios[i];12651265- if (bio->bi_end_io==NULL) continue;12671267+ if (bio->bi_end_io==NULL)12681268+ continue;12661269 /* remove last page from this bio */12671270 bio->bi_vcnt--;12681271 bio->bi_size -= len;
+3-13
drivers/media/dvb/frontends/lgdt3302.c
···217217 static u8 demux_ctrl_cfg[] = { DEMUX_CONTROL, 0xfb };218218 static u8 agc_rf_cfg[] = { AGC_RF_BANDWIDTH0, 0x40, 0x93, 0x00 };219219 static u8 agc_ctrl_cfg[] = { AGC_FUNC_CTRL2, 0xc6, 0x40 };220220- static u8 agc_delay_cfg[] = { AGC_DELAY0, 0x00, 0x00, 0x00 };220220+ static u8 agc_delay_cfg[] = { AGC_DELAY0, 0x07, 0x00, 0xfe };221221 static u8 agc_loop_cfg[] = { AGC_LOOP_BANDWIDTH0, 0x08, 0x9a };222222223223 /* Change only if we are actually changing the modulation */224224 if (state->current_modulation != param->u.vsb.modulation) {225225- int value;226226-227225 switch(param->u.vsb.modulation) {228226 case VSB_8:229227 dprintk("%s: VSB_8 MODE\n", __FUNCTION__);···274276 recovery center frequency register */275277 i2c_writebytes(state, state->config->demod_address,276278 vsb_freq_cfg, sizeof(vsb_freq_cfg));277277- /* Set the value of 'INLVTHD' register 0x2a/0x2c278278- to value from 'IFACC' register 0x39/0x3b -1 */279279- i2c_selectreadbytes(state, AGC_RFIF_ACC0,280280- &agc_delay_cfg[1], 3);281281- value = ((agc_delay_cfg[1] & 0x0f) << 8) | agc_delay_cfg[3];282282- value = value -1;283283- dprintk("%s IFACC -1 = 0x%03x\n", __FUNCTION__, value);284284- agc_delay_cfg[1] = (value >> 8) & 0x0f;285285- agc_delay_cfg[2] = 0x00;286286- agc_delay_cfg[3] = value & 0xff;279279+280280+ /* Set the value of 'INLVTHD' register 0x2a/0x2c to 0x7fe */287281 i2c_writebytes(state, state->config->demod_address,288282 agc_delay_cfg, sizeof(agc_delay_cfg));289283
+4-4
drivers/media/video/cx88/cx88-cards.c
···11/*22- * $Id: cx88-cards.c,v 1.85 2005/07/04 19:35:05 mkrufky Exp $22+ * $Id: cx88-cards.c,v 1.86 2005/07/14 03:06:43 mchehab Exp $33 *44 * device driver for Conexant 2388x based TV cards55 * card-specific stuff.···682682 .name = "PixelView PlayTV Ultra Pro (Stereo)",683683 /* May be also TUNER_YMEC_TVF_5533MF for NTSC/M or PAL/M */684684 .tuner_type = TUNER_PHILIPS_FM1216ME_MK3,685685- .radio_type = TUNER_TEA5767,686686- .tuner_addr = 0xc2>>1,687687- .radio_addr = 0xc0>>1,685685+ .radio_type = UNSET,686686+ .tuner_addr = ADDR_UNSET,687687+ .radio_addr = ADDR_UNSET,688688 .input = {{689689 .type = CX88_VMUX_TELEVISION,690690 .vmux = 0,
···22 * For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview33 * I2C address is allways 0xC0.44 *55- * $Id: tea5767.c,v 1.18 2005/07/07 03:02:55 mchehab Exp $55+ * $Id: tea5767.c,v 1.21 2005/07/14 03:06:43 mchehab Exp $66 *77 * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br)88 * This code is placed under the terms of the GNU General Public License···153153154154 switch (TEA5767_HIGH_LO_32768) {155155 case TEA5767_HIGH_LO_13MHz:156156- frq = 1000 * (div * 50 - 700 - 225) / 4; /* Freq in KHz */156156+ frq = (div * 50000 - 700000 - 225000) / 4; /* Freq in KHz */157157 break;158158 case TEA5767_LOW_LO_13MHz:159159- frq = 1000 * (div * 50 + 700 + 225) / 4; /* Freq in KHz */159159+ frq = (div * 50000 + 700000 + 225000) / 4; /* Freq in KHz */160160 break;161161 case TEA5767_LOW_LO_32768:162162- frq = 1000 * (div * 32768 / 1000 + 700 + 225) / 4; /* Freq in KHz */162162+ frq = (div * 32768 + 700000 + 225000) / 4; /* Freq in KHz */163163 break;164164 case TEA5767_HIGH_LO_32768:165165 default:166166- frq = 1000 * (div * 32768 / 1000 - 700 - 225) / 4; /* Freq in KHz */166166+ frq = (div * 32768 - 700000 - 225000) / 4; /* Freq in KHz */167167 break;168168 }169169 buffer[0] = (div >> 8) & 0x3f;···196196 unsigned div;197197 int rc;198198199199- tuner_dbg (PREFIX "radio freq counter %d\n", frq);199199+ tuner_dbg (PREFIX "radio freq = %d.%03d MHz\n", frq/16000,(frq/16)%1000);200200201201 /* Rounds freq to next decimal value - for 62.5 KHz step */202202 /* frq = 20*(frq/16)+radio_frq[frq%16]; */···224224 tuner_dbg ("TEA5767 radio HIGH LO inject xtal @ 13 MHz\n");225225 buffer[2] |= TEA5767_HIGH_LO_INJECT;226226 buffer[4] |= TEA5767_PLLREF_ENABLE;227227- div = (frq * 4 / 16 + 700 + 225 + 25) / 50;227227+ div = (frq * 4000 / 16 + 700000 + 225000 + 25000) / 50000;228228 break;229229 case TEA5767_LOW_LO_13MHz:230230 tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 13 MHz\n");231231232232 buffer[4] |= TEA5767_PLLREF_ENABLE;233233- div = (frq * 4 / 16 - 700 - 225 + 25) / 50;233233+ div = (frq * 4000 / 16 - 700000 - 225000 + 25000) / 50000;234234 break;235235 case TEA5767_LOW_LO_32768:236236 tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 32,768 MHz\n");237237 buffer[3] |= TEA5767_XTAL_32768;238238 /* const 700=4000*175 Khz - to adjust freq to right value */239239- div = (1000 * (frq * 4 / 16 - 700 - 225) + 16384) >> 15;239239+ div = ((frq * 4000 / 16 - 700000 - 225000) + 16384) >> 15;240240 break;241241 case TEA5767_HIGH_LO_32768:242242 default:···244244245245 buffer[2] |= TEA5767_HIGH_LO_INJECT;246246 buffer[3] |= TEA5767_XTAL_32768;247247- div = (1000 * (frq * 4 / 16 + 700 + 225) + 16384) >> 15;247247+ div = ((frq * (4000 / 16) + 700000 + 225000) + 16384) >> 15;248248 break;249249 }250250 buffer[0] = (div >> 8) & 0x3f;251251 buffer[1] = div & 0xff;252252253253- if (tuner_debug)254254- tea5767_status_dump(buffer);255255-256253 if (5 != (rc = i2c_master_send(c, buffer, 5)))257254 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);255255+256256+ if (tuner_debug) {257257+ if (5 != (rc = i2c_master_recv(c, buffer, 5)))258258+ tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);259259+ else260260+ tea5767_status_dump(buffer);261261+ }258262}259263260264static int tea5767_signal(struct i2c_client *c)···298294 struct tuner *t = i2c_get_clientdata(c);299295300296 if (5 != (rc = i2c_master_recv(c, buffer, 5))) {301301- tuner_warn("it is not a TEA5767. Received %i chars.\n", rc);297297+ tuner_warn("It is not a TEA5767. Received %i bytes.\n", rc);302298 return EINVAL;303299 }304300···314310 * bit 0 : internally set to 0315311 * Byte 5: bit 7:0 : == 0316312 */317317-318313 if (!((buffer[3] & 0x0f) == 0x00) && (buffer[4] == 0x00)) {319314 tuner_warn("Chip ID is not zero. It is not a TEA5767\n");320315 return EINVAL;321316 }317317+322318 tuner_warn("TEA5767 detected.\n");323319 return 0;324320}
+19-12
drivers/media/video/tuner-core.c
···11/*22- * $Id: tuner-core.c,v 1.55 2005/07/08 13:20:33 mchehab Exp $22+ * $Id: tuner-core.c,v 1.58 2005/07/14 03:06:43 mchehab Exp $33 *44 * i2c tv tuner chip device driver55 * core core, i.e. kernel interfaces, registering and so on···3838/* insmod options used at init time => read/only */3939static unsigned int addr = 0;4040module_param(addr, int, 0444);4141+4242+static unsigned int no_autodetect = 0;4343+module_param(no_autodetect, int, 0444);41444245/* insmod options used at runtime => read/write */4346unsigned int tuner_debug = 0;···321318 tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name);322319323320 /* TEA5767 autodetection code - only for addr = 0xc0 */324324- if (addr == 0x60) {325325- if (tea5767_autodetection(&t->i2c) != EINVAL) {326326- t->type = TUNER_TEA5767;327327- t->mode_mask = T_RADIO;328328- t->mode = T_STANDBY;329329- t->freq = 87.5 * 16; /* Sets freq to FM range */330330- default_mode_mask &= ~T_RADIO;321321+ if (!no_autodetect) {322322+ if (addr == 0x60) {323323+ if (tea5767_autodetection(&t->i2c) != EINVAL) {324324+ t->type = TUNER_TEA5767;325325+ t->mode_mask = T_RADIO;326326+ t->mode = T_STANDBY;327327+ t->freq = 87.5 * 16; /* Sets freq to FM range */328328+ default_mode_mask &= ~T_RADIO;331329332332- i2c_attach_client (&t->i2c);333333- set_type(&t->i2c,t->type, t->mode_mask);334334- return 0;330330+ i2c_attach_client (&t->i2c);331331+ set_type(&t->i2c,t->type, t->mode_mask);332332+ return 0;333333+ }335334 }336335 }337336···636631 break;637632 }638633 default:639639- tuner_dbg("Unimplemented IOCTL 0x%08x called to tuner.\n", cmd);634634+ tuner_dbg("Unimplemented IOCTL 0x%08x(dir=%d,tp=0x%02x,nr=%d,sz=%d)\n",635635+ cmd, _IOC_DIR(cmd), _IOC_TYPE(cmd),636636+ _IOC_NR(cmd), _IOC_SIZE(cmd));640637 break;641638 }642639
+1-1
drivers/mtd/chips/Kconfig
···300300301301config MTD_XIP302302 bool "XIP aware MTD support"303303- depends on !SMP && (MTD_CFI_INTELEXT || MTD_CFI_AMDSTD) && EXPERIMENTAL303303+ depends on !SMP && (MTD_CFI_INTELEXT || MTD_CFI_AMDSTD) && EXPERIMENTAL && ARM304304 default y if XIP_KERNEL305305 help306306 This allows MTD support to work with flash memory which is also
+4-1
drivers/mtd/chips/cfi_cmdset_0020.c
···44 *55 * (C) 2000 Red Hat. GPL'd66 *77- * $Id: cfi_cmdset_0020.c,v 1.17 2004/11/20 12:49:04 dwmw2 Exp $77+ * $Id: cfi_cmdset_0020.c,v 1.19 2005/07/13 15:52:45 dwmw2 Exp $88 * 99 * 10/10/2000 Nicolas Pitre <nico@cam.org>1010 * - completely revamped method functions so they are aware and···1616 * - modified Intel Command Set 0x0001 to support ST Advanced Architecture1717 * (command set 0x0020)1818 * - added a writev function1919+ * 07/13/2005 Joern Engel <joern@wh.fh-wedel.de>2020+ * - Plugged memory leak in cfi_staa_writev().1921 */20222123#include <linux/version.h>···721719write_error:722720 if (retlen)723721 *retlen = totlen;722722+ kfree(buffer);724723 return ret;725724}726725
+11-11
drivers/mtd/nand/nand_base.c
···5959 * The AG-AND chips have nice features for speed improvement,6060 * which are not supported yet. Read / program 4 pages in one go.6161 *6262- * $Id: nand_base.c,v 1.146 2005/06/17 15:02:06 gleixner Exp $6262+ * $Id: nand_base.c,v 1.147 2005/07/15 07:18:06 gleixner Exp $6363 *6464 * This program is free software; you can redistribute it and/or modify6565 * it under the terms of the GNU General Public License version 2 as···14091409 thislen = min_t(int, thislen, len);14101410 this->read_buf(mtd, &buf[i], thislen);14111411 i += thislen;14121412-14131413- /* Apply delay or wait for ready/busy pin 14141414- * Do this before the AUTOINCR check, so no problems14151415- * arise if a chip which does auto increment14161416- * is marked as NOAUTOINCR by the board driver.14171417- */14181418- if (!this->dev_ready) 14191419- udelay (this->chip_delay);14201420- else14211421- nand_wait_ready(mtd);1422141214231413 /* Read more ? */14241414 if (i < len) {···14221432 this->select_chip(mtd, chipnr);14231433 }1424143414351435+ /* Apply delay or wait for ready/busy pin 14361436+ * Do this before the AUTOINCR check, so no problems14371437+ * arise if a chip which does auto increment14381438+ * is marked as NOAUTOINCR by the board driver.14391439+ */14401440+ if (!this->dev_ready) 14411441+ udelay (this->chip_delay);14421442+ else14431443+ nand_wait_ready(mtd);14441444+14251445 /* Check, if the chip supports auto page increment 14261446 * or if we have hit a block boundary. 14271447 */
+9-11
drivers/mtd/nand/nand_bbt.c
···66 * 77 * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)88 *99- * $Id: nand_bbt.c,v 1.33 2005/06/14 15:47:56 gleixner Exp $99+ * $Id: nand_bbt.c,v 1.35 2005/07/15 13:53:47 gleixner Exp $1010 *1111 * This program is free software; you can redistribute it and/or modify1212 * it under the terms of the GNU General Public License version 2 as···109109/** 110110 * check_short_pattern - [GENERIC] check if a pattern is in the buffer111111 * @buf: the buffer to search112112- * @len: the length of buffer to search113113- * @paglen: the pagelength114112 * @td: search pattern descriptor115113 *116114 * Check for a pattern at the given place. Used to search bad block117115 * tables and good / bad block identifiers. Same as check_pattern, but 118118- * no optional empty check and the pattern is expected to start119119- * at offset 0.116116+ * no optional empty check120117 *121118*/122122-static int check_short_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td)119119+static int check_short_pattern (uint8_t *buf, struct nand_bbt_descr *td)123120{124121 int i;125122 uint8_t *p = buf;126123127124 /* Compare the pattern */128125 for (i = 0; i < td->len; i++) {129129- if (p[i] != td->pattern[i])126126+ if (p[td->offs + i] != td->pattern[i])130127 return -1;131128 }132129 return 0;···334337 if (!(bd->options & NAND_BBT_SCANEMPTY)) {335338 size_t retlen;336339337337- /* No need to read pages fully, just read required OOB bytes */338338- ret = mtd->read_oob(mtd, from + j * mtd->oobblock + bd->offs,339339- readlen, &retlen, &buf[0]);340340+ /* Read the full oob until read_oob is fixed to 341341+ * handle single byte reads for 16 bit buswidth */342342+ ret = mtd->read_oob(mtd, from + j * mtd->oobblock,343343+ mtd->oobsize, &retlen, buf);340344 if (ret)341345 return ret;342346343343- if (check_short_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {347347+ if (check_short_pattern (buf, bd)) {344348 this->bbt[i >> 3] |= 0x03 << (i & 0x6);345349 printk (KERN_WARNING "Bad eraseblock %d at 0x%08x\n", 346350 i >> 1, (unsigned int) from);
···2828#define __JSM_DRIVER_H29293030#include <linux/kernel.h>3131-#include <linux/version.h>3231#include <linux/types.h> /* To pick up the varions Linux types */3332#include <linux/tty.h>3433#include <linux/serial_core.h>
+111-115
drivers/usb/serial/option.c
···1212 History:13131414 2005-05-19 v0.1 Initial version, based on incomplete docs1515- and analysis of misbehavior of the standard driver1515+ and analysis of misbehavior with the standard driver1616 2005-05-20 v0.2 Extended the input buffer to avoid losing1717 random 64-byte chunks of data1818 2005-05-21 v0.3 implemented chars_in_buffer()1919 turned on low_latency2020 simplified the code somewhat2121+ 2005-05-24 v0.4 option_write() sometimes deadlocked under heavy load2222+ removed some dead code2323+ added sponsor notice2424+ coding style clean-up2525+ 2005-06-20 v0.4.1 add missing braces :-/2626+ killed end-of-line whitespace2727+ 2005-07-15 v0.4.2 rename WLAN product to FUSION, add FUSION22828+2929+ Work sponsored by: Sigos GmbH, Germany <info@sigos.de>3030+2131*/2222-#define DRIVER_VERSION "v0.3"3232+3333+#define DRIVER_VERSION "v0.4"2334#define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>"2435#define DRIVER_DESC "Option Card (PC-Card to) USB to Serial Driver"2536···55445645static void option_instat_callback(struct urb *urb, struct pt_regs *regs);57465858-5947static int option_write (struct usb_serial_port *port,6048 const unsigned char *buf, int count);6149···7060static int option_send_setup (struct usb_serial_port *port);71617262/* Vendor and product IDs */7373-#define OPTION_VENDOR_ID 0x0AF06363+#define OPTION_VENDOR_ID 0x0AF074647575-#define OPTION_PRODUCT_OLD 0x50007676-#define OPTION_PRODUCT_WLAN 0x60006565+#define OPTION_PRODUCT_OLD 0x50006666+#define OPTION_PRODUCT_FUSION 0x60006767+#define OPTION_PRODUCT_FUSION2 0x63006868+77697870static struct usb_device_id option_ids[] = {7971 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) },8080- { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_WLAN) },7272+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) },7373+ { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) },8174 { } /* Terminating entry */8275};8376···9885 * recognizes separately, thus num_port=1.9986 */10087static struct usb_serial_device_type option_3port_device = {101101- .owner = THIS_MODULE,102102- .name = "Option 3-port card",103103- .short_name = "option",104104- .id_table = option_ids,105105- .num_interrupt_in = NUM_DONT_CARE,106106- .num_bulk_in = NUM_DONT_CARE,107107- .num_bulk_out = NUM_DONT_CARE,108108- .num_ports = 1, /* 3 */109109- .open = option_open,110110- .close = option_close,111111- .write = option_write,112112- .write_room = option_write_room,113113- .chars_in_buffer = option_chars_in_buffer,114114- .throttle = option_rx_throttle,115115- .unthrottle = option_rx_unthrottle,116116- .ioctl = option_ioctl,117117- .set_termios = option_set_termios,118118- .break_ctl = option_break_ctl,119119- .tiocmget = option_tiocmget,120120- .tiocmset = option_tiocmset,121121- .attach = option_startup,122122- .shutdown = option_shutdown,123123- .read_int_callback = option_instat_callback,8888+ .owner = THIS_MODULE,8989+ .name = "Option 3G data card",9090+ .short_name = "option",9191+ .id_table = option_ids,9292+ .num_interrupt_in = NUM_DONT_CARE,9393+ .num_bulk_in = NUM_DONT_CARE,9494+ .num_bulk_out = NUM_DONT_CARE,9595+ .num_ports = 1, /* 3, but the card reports its ports separately */9696+ .open = option_open,9797+ .close = option_close,9898+ .write = option_write,9999+ .write_room = option_write_room,100100+ .chars_in_buffer = option_chars_in_buffer,101101+ .throttle = option_rx_throttle,102102+ .unthrottle = option_rx_unthrottle,103103+ .ioctl = option_ioctl,104104+ .set_termios = option_set_termios,105105+ .break_ctl = option_break_ctl,106106+ .tiocmget = option_tiocmget,107107+ .tiocmset = option_tiocmset,108108+ .attach = option_startup,109109+ .shutdown = option_shutdown,110110+ .read_int_callback = option_instat_callback,124111};125112113113+#ifdef CONFIG_USB_DEBUG126114static int debug;115115+#else116116+#define debug 0117117+#endif118118+127119128120/* per port private data */129121130130-#define N_IN_URB 4131131-#define N_OUT_URB 1132132-#define IN_BUFLEN 1024133133-#define OUT_BUFLEN 1024122122+#define N_IN_URB 4123123+#define N_OUT_URB 1124124+#define IN_BUFLEN 1024125125+#define OUT_BUFLEN 128134126135127struct option_port_private {136128 /* Input endpoints and buffer for this port */137137- struct urb *in_urbs[N_IN_URB];138138- char in_buffer[N_IN_URB][IN_BUFLEN];129129+ struct urb *in_urbs[N_IN_URB];130130+ char in_buffer[N_IN_URB][IN_BUFLEN];139131 /* Output endpoints and buffer for this port */140140- struct urb *out_urbs[N_OUT_URB];141141- char out_buffer[N_OUT_URB][OUT_BUFLEN];132132+ struct urb *out_urbs[N_OUT_URB];133133+ char out_buffer[N_OUT_URB][OUT_BUFLEN];142134143135 /* Settings for the port */144144- int rts_state; /* Handshaking pins (outputs) */145145- int dtr_state;146146- int cts_state; /* Handshaking pins (inputs) */147147- int dsr_state;148148- int dcd_state;149149- int ri_state;150150- // int break_on;136136+ int rts_state; /* Handshaking pins (outputs) */137137+ int dtr_state;138138+ int cts_state; /* Handshaking pins (inputs) */139139+ int dsr_state;140140+ int dcd_state;141141+ int ri_state;151142152152- unsigned long tx_start_time[N_OUT_URB];143143+ unsigned long tx_start_time[N_OUT_URB];153144};154145155146···207190option_break_ctl (struct usb_serial_port *port, int break_state)208191{209192 /* Unfortunately, I don't know how to send a break */210210- dbg("%s", __FUNCTION__);193193+ dbg("%s", __FUNCTION__);211194}212195213196214197static void215198option_set_termios (struct usb_serial_port *port,216216- struct termios *old_termios)199199+ struct termios *old_termios)217200{218201 dbg("%s", __FUNCTION__);219202···221204}222205223206static int224224-option_tiocmget(struct usb_serial_port *port, struct file *file)207207+option_tiocmget (struct usb_serial_port *port, struct file *file)225208{226226- unsigned int value;227227- struct option_port_private *portdata;209209+ unsigned int value;210210+ struct option_port_private *portdata;228211229212 portdata = usb_get_serial_port_data(port);230213···242225option_tiocmset (struct usb_serial_port *port, struct file *file,243226 unsigned int set, unsigned int clear)244227{245245- struct option_port_private *portdata;228228+ struct option_port_private *portdata;246229247230 portdata = usb_get_serial_port_data(port);248231···267250268251/* Write */269252static int270270-option_write(struct usb_serial_port *port,271271- const unsigned char *buf, int count)253253+option_write (struct usb_serial_port *port,254254+ const unsigned char *buf, int count)272255{273273- struct option_port_private *portdata;274274- int i;275275- int left, todo;276276- struct urb *this_urb = NULL; /* spurious */277277- int err;256256+ struct option_port_private *portdata;257257+ int i;258258+ int left, todo;259259+ struct urb *this_urb = NULL; /* spurious */260260+ int err;278261279262 portdata = usb_get_serial_port_data(port);280263281264 dbg("%s: write (%d chars)", __FUNCTION__, count);282265283283-#if 0284284- spin_lock(&port->lock);285285- if (port->write_urb_busy) {286286- spin_unlock(&port->lock);287287- dbg("%s: already writing", __FUNCTION__);288288- return 0;289289- }290290- port->write_urb_busy = 1;291291- spin_unlock(&port->lock);292292-#endif293293-294266 i = 0;295267 left = count;296296- while (left>0) {268268+ for (i=0; left > 0 && i < N_OUT_URB; i++) {297269 todo = left;298270 if (todo > OUT_BUFLEN)299271 todo = OUT_BUFLEN;300272301301- for (;i < N_OUT_URB; i++) {302302- /* Check we have a valid urb/endpoint before we use it... */303303- this_urb = portdata->out_urbs[i];304304- if (this_urb->status != -EINPROGRESS)305305- break;273273+ this_urb = portdata->out_urbs[i];274274+ if (this_urb->status == -EINPROGRESS) {306275 if (this_urb->transfer_flags & URB_ASYNC_UNLINK)307276 continue;308277 if (time_before(jiffies, portdata->tx_start_time[i] + 10 * HZ))309278 continue;310279 this_urb->transfer_flags |= URB_ASYNC_UNLINK;311280 usb_unlink_urb(this_urb);281281+ continue;312282 }313313-314314- if (i == N_OUT_URB) {315315- /* no bulk out free! */316316- dbg("%s: no output urb -- left %d", __FUNCTION__,count-left);317317-#if 0318318- port->write_urb_busy = 0;319319-#endif320320- return count-left;321321- }283283+ if (this_urb->status != 0)284284+ dbg("usb_write %p failed (err=%d)", this_urb, this_urb->status);322285323286 dbg("%s: endpoint %d buf %d", __FUNCTION__, usb_pipeendpoint(this_urb->pipe), i);324287288288+ /* send the data */325289 memcpy (this_urb->transfer_buffer, buf, todo);326326-327327- /* send the data out the bulk port */328290 this_urb->transfer_buffer_length = todo;329291330292 this_urb->transfer_flags &= ~URB_ASYNC_UNLINK;331293 this_urb->dev = port->serial->dev;332294 err = usb_submit_urb(this_urb, GFP_ATOMIC);333295 if (err) {334334- dbg("usb_submit_urb %p (write bulk) failed (%d,, has %d)", this_urb, err, this_urb->status);296296+ dbg("usb_submit_urb %p (write bulk) failed (%d, has %d)", this_urb, err, this_urb->status);335297 continue;336298 }337299 portdata->tx_start_time[i] = jiffies;···319323 }320324321325 count -= left;322322-#if 0323323- port->write_urb_busy = 0;324324-#endif325326 dbg("%s: wrote (did %d)", __FUNCTION__, count);326327 return count;327328}···326333static void327334option_indat_callback (struct urb *urb, struct pt_regs *regs)328335{329329- int i, err;336336+ int i, err;330337 int endpoint;331338 struct usb_serial_port *port;332339 struct tty_struct *tty;···437444438445 portdata = usb_get_serial_port_data(port);439446440440- for (i=0; i < N_OUT_URB; i++)447447+ for (i=0; i < N_OUT_URB; i++) {441448 this_urb = portdata->out_urbs[i];442449 if (this_urb && this_urb->status != -EINPROGRESS)443450 data_len += OUT_BUFLEN;451451+ }444452445453 dbg("%s: %d", __FUNCTION__, data_len);446454 return data_len;···458464459465 portdata = usb_get_serial_port_data(port);460466461461- for (i=0; i < N_OUT_URB; i++)467467+ for (i=0; i < N_OUT_URB; i++) {462468 this_urb = portdata->out_urbs[i];463469 if (this_urb && this_urb->status == -EINPROGRESS)464470 data_len += this_urb->transfer_buffer_length;465465-471471+ }466472 dbg("%s: %d", __FUNCTION__, data_len);467473 return data_len;468474}···471477static int472478option_open (struct usb_serial_port *port, struct file *filp)473479{474474- struct option_port_private *portdata;475475- struct usb_serial *serial = port->serial;476476- int i, err;477477- struct urb *urb;480480+ struct option_port_private *portdata;481481+ struct usb_serial *serial = port->serial;482482+ int i, err;483483+ struct urb *urb;478484479485 portdata = usb_get_serial_port_data(port);480486···522528}523529524530static inline void525525-stop_urb(struct urb *urb)531531+stop_urb (struct urb *urb)526532{527533 if (urb && urb->status == -EINPROGRESS) {528534 urb->transfer_flags &= ~URB_ASYNC_UNLINK;···531537}532538533539static void534534-option_close(struct usb_serial_port *port, struct file *filp)540540+option_close (struct usb_serial_port *port, struct file *filp)535541{536536- int i;537537- struct usb_serial *serial = port->serial;538538- struct option_port_private *portdata;542542+ int i;543543+ struct usb_serial *serial = port->serial;544544+ struct option_port_private *portdata;539545540546 dbg("%s", __FUNCTION__);541547 portdata = usb_get_serial_port_data(port);···583589584590/* Setup urbs */585591static void586586-option_setup_urbs(struct usb_serial *serial)592592+option_setup_urbs (struct usb_serial *serial)587593{588588- int j;589589- struct usb_serial_port *port;590590- struct option_port_private *portdata;594594+ int j;595595+ struct usb_serial_port *port;596596+ struct option_port_private *portdata;591597592598 dbg("%s", __FUNCTION__);593599···611617612618613619static int614614-option_send_setup(struct usb_serial_port *port)620620+option_send_setup (struct usb_serial_port *port)615621{616622 struct usb_serial *serial = port->serial;617623 struct option_port_private *portdata;···638644static int639645option_startup (struct usb_serial *serial)640646{641641- int i, err;642642- struct usb_serial_port *port;643643- struct option_port_private *portdata;647647+ int i, err;648648+ struct usb_serial_port *port;649649+ struct option_port_private *portdata;644650645651 dbg("%s", __FUNCTION__);646652···671677static void672678option_shutdown (struct usb_serial *serial)673679{674674- int i, j;675675- struct usb_serial_port *port;676676- struct option_port_private *portdata;680680+ int i, j;681681+ struct usb_serial_port *port;682682+ struct option_port_private *portdata;677683678684 dbg("%s", __FUNCTION__);679685···718724MODULE_VERSION(DRIVER_VERSION);719725MODULE_LICENSE("GPL");720726727727+#ifdef CONFIG_USB_DEBUG721728module_param(debug, bool, S_IRUGO | S_IWUSR);722729MODULE_PARM_DESC(debug, "Debug messages");730730+#endif723731
+47-34
fs/ext2/xip.c
···1515#include "xip.h"16161717static inline int1818-__inode_direct_access(struct inode *inode, sector_t sector, unsigned long *data) {1818+__inode_direct_access(struct inode *inode, sector_t sector,1919+ unsigned long *data)2020+{1921 BUG_ON(!inode->i_sb->s_bdev->bd_disk->fops->direct_access);2022 return inode->i_sb->s_bdev->bd_disk->fops2123 ->direct_access(inode->i_sb->s_bdev,sector,data);2224}23252626+static inline int2727+__ext2_get_sector(struct inode *inode, sector_t offset, int create,2828+ sector_t *result)2929+{3030+ struct buffer_head tmp;3131+ int rc;3232+3333+ memset(&tmp, 0, sizeof(struct buffer_head));3434+ rc = ext2_get_block(inode, offset/ (PAGE_SIZE/512), &tmp,3535+ create);3636+ *result = tmp.b_blocknr;3737+3838+ /* did we get a sparse block (hole in the file)? */3939+ if (!(*result)) {4040+ BUG_ON(create);4141+ rc = -ENODATA;4242+ }4343+4444+ return rc;4545+}4646+2447int2525-ext2_clear_xip_target(struct inode *inode, int block) {2626- sector_t sector = block*(PAGE_SIZE/512);4848+ext2_clear_xip_target(struct inode *inode, int block)4949+{5050+ sector_t sector = block * (PAGE_SIZE/512);2751 unsigned long data;2852 int rc;29533054 rc = __inode_direct_access(inode, sector, &data);3131- if (rc)3232- return rc;3333- clear_page((void*)data);3434- return 0;5555+ if (!rc)5656+ clear_page((void*)data);5757+ return rc;3558}36593760void ext2_xip_verify_sb(struct super_block *sb)3861{3962 struct ext2_sb_info *sbi = EXT2_SB(sb);40634141- if ((sbi->s_mount_opt & EXT2_MOUNT_XIP)) {4242- if ((sb->s_bdev == NULL) ||4343- sb->s_bdev->bd_disk == NULL ||4444- sb->s_bdev->bd_disk->fops == NULL ||4545- sb->s_bdev->bd_disk->fops->direct_access == NULL) {4646- sbi->s_mount_opt &= (~EXT2_MOUNT_XIP);4747- ext2_warning(sb, __FUNCTION__,4848- "ignoring xip option - not supported by bdev");4949- }6464+ if ((sbi->s_mount_opt & EXT2_MOUNT_XIP) &&6565+ !sb->s_bdev->bd_disk->fops->direct_access) {6666+ sbi->s_mount_opt &= (~EXT2_MOUNT_XIP);6767+ ext2_warning(sb, __FUNCTION__,6868+ "ignoring xip option - not supported by bdev");5069 }5170}52715353-struct page*5454-ext2_get_xip_page(struct address_space *mapping, sector_t blockno,7272+struct page *7373+ext2_get_xip_page(struct address_space *mapping, sector_t offset,5574 int create)5675{5776 int rc;5877 unsigned long data;5959- struct buffer_head tmp;7878+ sector_t sector;60796161- tmp.b_state = 0;6262- tmp.b_blocknr = 0;6363- rc = ext2_get_block(mapping->host, blockno/(PAGE_SIZE/512) , &tmp,6464- create);8080+ /* first, retrieve the sector number */8181+ rc = __ext2_get_sector(mapping->host, offset, create, §or);6582 if (rc)6666- return ERR_PTR(rc);6767- if (tmp.b_blocknr == 0) {6868- /* SPARSE block */6969- BUG_ON(create);7070- return ERR_PTR(-ENODATA);7171- }8383+ goto error;72848585+ /* retrieve address of the target data */7386 rc = __inode_direct_access7474- (mapping->host,tmp.b_blocknr*(PAGE_SIZE/512) ,&data);7575- if (rc)7676- return ERR_PTR(rc);8787+ (mapping->host, sector * (PAGE_SIZE/512), &data);8888+ if (!rc)8989+ return virt_to_page(data);77907878- SetPageUptodate(virt_to_page(data));7979- return virt_to_page(data);9191+ error:9292+ return ERR_PTR(rc);8093}
···757757 * @head: the head of the list to search758758 * @test: callback used for comparisons between inodes759759 * @data: opaque data pointer to pass to @test760760+ * @wait: if true wait for the inode to be unlocked, if false do not760761 *761762 * ifind() searches for the inode specified by @data in the inode762763 * cache. This is a generalized version of ifind_fast() for file systems where···772771 */773772static inline struct inode *ifind(struct super_block *sb,774773 struct hlist_head *head, int (*test)(struct inode *, void *),775775- void *data)774774+ void *data, const int wait)776775{777776 struct inode *inode;778777···781780 if (inode) {782781 __iget(inode);783782 spin_unlock(&inode_lock);784784- wait_on_inode(inode);783783+ if (likely(wait))784784+ wait_on_inode(inode);785785 return inode;786786 }787787 spin_unlock(&inode_lock);···822820}823821824822/**825825- * ilookup5 - search for an inode in the inode cache823823+ * ilookup5_nowait - search for an inode in the inode cache826824 * @sb: super block of file system to search827825 * @hashval: hash value (usually inode number) to search for828826 * @test: callback used for comparisons between inodes···834832 * identification of an inode.835833 *836834 * If the inode is in the cache, the inode is returned with an incremented837837- * reference count.835835+ * reference count. Note, the inode lock is not waited upon so you have to be836836+ * very careful what you do with the returned inode. You probably should be837837+ * using ilookup5() instead.838838+ *839839+ * Otherwise NULL is returned.840840+ *841841+ * Note, @test is called with the inode_lock held, so can't sleep.842842+ */843843+struct inode *ilookup5_nowait(struct super_block *sb, unsigned long hashval,844844+ int (*test)(struct inode *, void *), void *data)845845+{846846+ struct hlist_head *head = inode_hashtable + hash(sb, hashval);847847+848848+ return ifind(sb, head, test, data, 0);849849+}850850+851851+EXPORT_SYMBOL(ilookup5_nowait);852852+853853+/**854854+ * ilookup5 - search for an inode in the inode cache855855+ * @sb: super block of file system to search856856+ * @hashval: hash value (usually inode number) to search for857857+ * @test: callback used for comparisons between inodes858858+ * @data: opaque data pointer to pass to @test859859+ *860860+ * ilookup5() uses ifind() to search for the inode specified by @hashval and861861+ * @data in the inode cache. This is a generalized version of ilookup() for862862+ * file systems where the inode number is not sufficient for unique863863+ * identification of an inode.864864+ *865865+ * If the inode is in the cache, the inode lock is waited upon and the inode is866866+ * returned with an incremented reference count.838867 *839868 * Otherwise NULL is returned.840869 *···876843{877844 struct hlist_head *head = inode_hashtable + hash(sb, hashval);878845879879- return ifind(sb, head, test, data);846846+ return ifind(sb, head, test, data, 1);880847}881848882849EXPORT_SYMBOL(ilookup5);···933900 struct hlist_head *head = inode_hashtable + hash(sb, hashval);934901 struct inode *inode;935902936936- inode = ifind(sb, head, test, data);903903+ inode = ifind(sb, head, test, data, 1);937904 if (inode)938905 return inode;939906 /*
···77 *88 * For licensing information, see the file 'LICENCE' in this directory.99 *1010- * $Id: build.c,v 1.70 2005/02/28 08:21:05 dedekind Exp $1010+ * $Id: build.c,v 1.71 2005/07/12 16:37:08 dedekind Exp $1111 *1212 */1313···335335 c->blocks[i].last_node = NULL;336336 c->blocks[i].bad_count = 0;337337 }338338-339339- init_MUTEX(&c->alloc_sem);340340- init_MUTEX(&c->erase_free_sem);341341- init_waitqueue_head(&c->erase_wait);342342- init_waitqueue_head(&c->inocache_wq);343343- spin_lock_init(&c->erase_completion_lock);344344- spin_lock_init(&c->inocache_lock);345338346339 INIT_LIST_HEAD(&c->clean_list);347340 INIT_LIST_HEAD(&c->very_dirty_list);
+96-86
fs/jffs2/erase.c
···77 *88 * For licensing information, see the file 'LICENCE' in this directory.99 *1010- * $Id: erase.c,v 1.76 2005/05/03 15:11:40 dedekind Exp $1010+ * $Id: erase.c,v 1.80 2005/07/14 19:46:24 joern Exp $1111 *1212 */1313···300300 jeb->last_node = NULL;301301}302302303303+static int jffs2_block_check_erase(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t *bad_offset)304304+{305305+ void *ebuf;306306+ uint32_t ofs;307307+ size_t retlen;308308+ int ret = -EIO;309309+310310+ ebuf = kmalloc(PAGE_SIZE, GFP_KERNEL);311311+ if (!ebuf) {312312+ printk(KERN_WARNING "Failed to allocate page buffer for verifying erase at 0x%08x. Refiling\n", jeb->offset);313313+ return -EAGAIN;314314+ }315315+316316+ D1(printk(KERN_DEBUG "Verifying erase at 0x%08x\n", jeb->offset));317317+318318+ for (ofs = jeb->offset; ofs < jeb->offset + c->sector_size; ) {319319+ uint32_t readlen = min((uint32_t)PAGE_SIZE, jeb->offset + c->sector_size - ofs);320320+ int i;321321+322322+ *bad_offset = ofs;323323+324324+ ret = jffs2_flash_read(c, ofs, readlen, &retlen, ebuf);325325+ if (ret) {326326+ printk(KERN_WARNING "Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n", ofs, ret);327327+ goto fail;328328+ }329329+ if (retlen != readlen) {330330+ printk(KERN_WARNING "Short read from newly-erased block at 0x%08x. Wanted %d, got %zd\n", ofs, readlen, retlen);331331+ goto fail;332332+ }333333+ for (i=0; i<readlen; i += sizeof(unsigned long)) {334334+ /* It's OK. We know it's properly aligned */335335+ unsigned long *datum = ebuf + i;336336+ if (*datum + 1) {337337+ *bad_offset += i;338338+ printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08x\n", *datum, *bad_offset);339339+ goto fail;340340+ }341341+ }342342+ ofs += readlen;343343+ cond_resched();344344+ }345345+ ret = 0;346346+fail:347347+ kfree(ebuf);348348+ return ret;349349+}350350+303351static void jffs2_mark_erased_block(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)304352{305353 struct jffs2_raw_node_ref *marker_ref = NULL;306306- unsigned char *ebuf;307354 size_t retlen;308355 int ret;309356 uint32_t bad_offset;310357311311- if ((!jffs2_cleanmarker_oob(c)) && (c->cleanmarker_size > 0)) {312312- marker_ref = jffs2_alloc_raw_node_ref();313313- if (!marker_ref) {314314- printk(KERN_WARNING "Failed to allocate raw node ref for clean marker\n");315315- /* Stick it back on the list from whence it came and come back later */316316- jffs2_erase_pending_trigger(c);317317- spin_lock(&c->erase_completion_lock);318318- list_add(&jeb->list, &c->erase_complete_list);319319- spin_unlock(&c->erase_completion_lock);320320- return;321321- }358358+ switch (jffs2_block_check_erase(c, jeb, &bad_offset)) {359359+ case -EAGAIN: goto refile;360360+ case -EIO: goto filebad;322361 }323323- ebuf = kmalloc(PAGE_SIZE, GFP_KERNEL);324324- if (!ebuf) {325325- printk(KERN_WARNING "Failed to allocate page buffer for verifying erase at 0x%08x. Assuming it worked\n", jeb->offset);326326- } else {327327- uint32_t ofs = jeb->offset;328328-329329- D1(printk(KERN_DEBUG "Verifying erase at 0x%08x\n", jeb->offset));330330- while(ofs < jeb->offset + c->sector_size) {331331- uint32_t readlen = min((uint32_t)PAGE_SIZE, jeb->offset + c->sector_size - ofs);332332- int i;333333-334334- bad_offset = ofs;335335-336336- ret = c->mtd->read(c->mtd, ofs, readlen, &retlen, ebuf);337337-338338- if (ret) {339339- printk(KERN_WARNING "Read of newly-erased block at 0x%08x failed: %d. Putting on bad_list\n", ofs, ret);340340- goto bad;341341- }342342- if (retlen != readlen) {343343- printk(KERN_WARNING "Short read from newly-erased block at 0x%08x. Wanted %d, got %zd\n", ofs, readlen, retlen);344344- goto bad;345345- }346346- for (i=0; i<readlen; i += sizeof(unsigned long)) {347347- /* It's OK. We know it's properly aligned */348348- unsigned long datum = *(unsigned long *)(&ebuf[i]);349349- if (datum + 1) {350350- bad_offset += i;351351- printk(KERN_WARNING "Newly-erased block contained word 0x%lx at offset 0x%08x\n", datum, bad_offset);352352- bad: 353353- if ((!jffs2_cleanmarker_oob(c)) && (c->cleanmarker_size > 0))354354- jffs2_free_raw_node_ref(marker_ref);355355- kfree(ebuf);356356- bad2:357357- spin_lock(&c->erase_completion_lock);358358- /* Stick it on a list (any list) so359359- erase_failed can take it right off360360- again. Silly, but shouldn't happen361361- often. */362362- list_add(&jeb->list, &c->erasing_list);363363- spin_unlock(&c->erase_completion_lock);364364- jffs2_erase_failed(c, jeb, bad_offset);365365- return;366366- }367367- }368368- ofs += readlen;369369- cond_resched();370370- }371371- kfree(ebuf);372372- }373373-374374- bad_offset = jeb->offset;375362376363 /* Write the erase complete marker */ 377364 D1(printk(KERN_DEBUG "Writing erased marker to block at 0x%08x\n", jeb->offset));378378- if (jffs2_cleanmarker_oob(c)) {365365+ bad_offset = jeb->offset;379366380380- if (jffs2_write_nand_cleanmarker(c, jeb))381381- goto bad2;382382-367367+ /* Cleanmarker in oob area or no cleanmarker at all ? */368368+ if (jffs2_cleanmarker_oob(c) || c->cleanmarker_size == 0) {369369+370370+ if (jffs2_cleanmarker_oob(c)) {371371+ if (jffs2_write_nand_cleanmarker(c, jeb))372372+ goto filebad;373373+ }374374+383375 jeb->first_node = jeb->last_node = NULL;384384-385376 jeb->free_size = c->sector_size;386377 jeb->used_size = 0;387378 jeb->dirty_size = 0;388379 jeb->wasted_size = 0;389389- } else if (c->cleanmarker_size == 0) {390390- jeb->first_node = jeb->last_node = NULL;391380392392- jeb->free_size = c->sector_size;393393- jeb->used_size = 0;394394- jeb->dirty_size = 0;395395- jeb->wasted_size = 0;396381 } else {382382+397383 struct kvec vecs[1];398384 struct jffs2_unknown_node marker = {399385 .magic = cpu_to_je16(JFFS2_MAGIC_BITMASK),···387401 .totlen = cpu_to_je32(c->cleanmarker_size)388402 };389403404404+ marker_ref = jffs2_alloc_raw_node_ref();405405+ if (!marker_ref) {406406+ printk(KERN_WARNING "Failed to allocate raw node ref for clean marker. Refiling\n");407407+ goto refile;408408+ }409409+390410 marker.hdr_crc = cpu_to_je32(crc32(0, &marker, sizeof(struct jffs2_unknown_node)-4));391411392412 vecs[0].iov_base = (unsigned char *) ▮393413 vecs[0].iov_len = sizeof(marker);394414 ret = jffs2_flash_direct_writev(c, vecs, 1, jeb->offset, &retlen);395415396396- if (ret) {397397- printk(KERN_WARNING "Write clean marker to block at 0x%08x failed: %d\n",398398- jeb->offset, ret);399399- goto bad2;400400- }401401- if (retlen != sizeof(marker)) {402402- printk(KERN_WARNING "Short write to newly-erased block at 0x%08x: Wanted %zd, got %zd\n",403403- jeb->offset, sizeof(marker), retlen);404404- goto bad2;416416+ if (ret || retlen != sizeof(marker)) {417417+ if (ret)418418+ printk(KERN_WARNING "Write clean marker to block at 0x%08x failed: %d\n",419419+ jeb->offset, ret);420420+ else421421+ printk(KERN_WARNING "Short write to newly-erased block at 0x%08x: Wanted %zd, got %zd\n",422422+ jeb->offset, sizeof(marker), retlen);423423+424424+ jffs2_free_raw_node_ref(marker_ref);425425+ goto filebad;405426 }406427407428 marker_ref->next_in_ino = NULL;···437444 c->nr_free_blocks++;438445 spin_unlock(&c->erase_completion_lock);439446 wake_up(&c->erase_wait);440440-}447447+ return;441448449449+filebad:450450+ spin_lock(&c->erase_completion_lock);451451+ /* Stick it on a list (any list) so erase_failed can take it452452+ right off again. Silly, but shouldn't happen often. */453453+ list_add(&jeb->list, &c->erasing_list);454454+ spin_unlock(&c->erase_completion_lock);455455+ jffs2_erase_failed(c, jeb, bad_offset);456456+ return;457457+458458+refile:459459+ /* Stick it back on the list from whence it came and come back later */460460+ jffs2_erase_pending_trigger(c);461461+ spin_lock(&c->erase_completion_lock);462462+ list_add(&jeb->list, &c->erase_complete_list);463463+ spin_unlock(&c->erase_completion_lock);464464+ return;465465+}
+7-7
fs/jffs2/nodelist.c
···77 *88 * For licensing information, see the file 'LICENCE' in this directory.99 *1010- * $Id: nodelist.c,v 1.97 2005/07/06 15:18:41 dwmw2 Exp $1010+ * $Id: nodelist.c,v 1.98 2005/07/10 15:15:32 dedekind Exp $1111 *1212 */1313···5555 });5656}57575858-/* Put a new tmp_dnode_info into the list, keeping the list in 5959- order of increasing version6060-*/6161-6262-static void jffs2_add_tn_to_list(struct jffs2_tmp_dnode_info *tn, struct rb_root *list)5858+/* 5959+ * Put a new tmp_dnode_info into the temporaty RB-tree, keeping the list in 6060+ * order of increasing version.6161+ */6262+static void jffs2_add_tn_to_tree(struct jffs2_tmp_dnode_info *tn, struct rb_root *list)6363{6464 struct rb_node **p = &list->rb_node;6565 struct rb_node * parent = NULL;···420420 D1(printk(KERN_DEBUG "dnode @%08x: ver %u, offset %04x, dsize %04x\n",421421 ref_offset(ref), je32_to_cpu(node.i.version),422422 je32_to_cpu(node.i.offset), je32_to_cpu(node.i.dsize)));423423- jffs2_add_tn_to_list(tn, &ret_tn);423423+ jffs2_add_tn_to_tree(tn, &ret_tn);424424 break;425425426426 default:
+3-1
fs/jffs2/os-linux.h
···77 *88 * For licensing information, see the file 'LICENCE' in this directory.99 *1010- * $Id: os-linux.h,v 1.57 2005/07/06 12:13:09 dwmw2 Exp $1010+ * $Id: os-linux.h,v 1.58 2005/07/12 02:34:35 tpoynor Exp $1111 *1212 */1313···8686#define jffs2_dataflash(c) (0)8787#define jffs2_nor_ecc_flash_setup(c) (0)8888#define jffs2_nor_ecc_flash_cleanup(c) do {} while (0)8989+#define jffs2_dataflash_setup(c) (0)9090+#define jffs2_dataflash_cleanup(c) do {} while (0)89919092#else /* NAND and/or ECC'd NOR support present */9193
+4-7
fs/jffs2/readinode.c
···77 *88 * For licensing information, see the file 'LICENCE' in this directory.99 *1010- * $Id: readinode.c,v 1.120 2005/07/05 21:03:07 dwmw2 Exp $1010+ * $Id: readinode.c,v 1.125 2005/07/10 13:13:55 dedekind Exp $1111 *1212 */1313···151151152152 D1(printk(KERN_DEBUG "jffs2_add_full_dnode_to_inode(ino #%u, f %p, fn %p)\n", f->inocache->ino, f, fn));153153154154+ if (unlikely(!fn->size))155155+ return 0;156156+154157 newfrag = jffs2_alloc_node_frag();155158 if (unlikely(!newfrag))156159 return -ENOMEM;···161158 D2(printk(KERN_DEBUG "adding node %04x-%04x @0x%08x on flash, newfrag *%p\n",162159 fn->ofs, fn->ofs+fn->size, ref_offset(fn->raw), newfrag));163160164164- if (unlikely(!fn->size)) {165165- jffs2_free_node_frag(newfrag);166166- return 0;167167- }168168-169161 newfrag->ofs = fn->ofs;170162 newfrag->size = fn->size;171163 newfrag->node = fn;···558560 }559561 next_tn:560562 BUG_ON(rb->rb_left);561561- repl_rb = NULL;562563 if (rb->rb_parent && rb->rb_parent->rb_left == rb) {563564 /* We were then left-hand child of our parent. We need564565 to move our own right-hand child into our place. */
+10-1
fs/jffs2/super.c
···77 *88 * For licensing information, see the file 'LICENCE' in this directory.99 *1010- * $Id: super.c,v 1.106 2005/05/18 11:37:25 dedekind Exp $1010+ * $Id: super.c,v 1.107 2005/07/12 16:37:08 dedekind Exp $1111 *1212 */1313···139139140140 D1(printk(KERN_DEBUG "jffs2_get_sb_mtd(): New superblock for device %d (\"%s\")\n",141141 mtd->index, mtd->name));142142+143143+ /* Initialize JFFS2 superblock locks, the further initialization will be144144+ * done later */145145+ init_MUTEX(&c->alloc_sem);146146+ init_MUTEX(&c->erase_free_sem);147147+ init_waitqueue_head(&c->erase_wait);148148+ init_waitqueue_head(&c->inocache_wq);149149+ spin_lock_init(&c->erase_completion_lock);150150+ spin_lock_init(&c->inocache_lock);142151143152 sb->s_op = &jffs2_super_operations;144153 sb->s_flags = flags | MS_NOATIME;
···5151 }5252 } else {5353 for (i = 0; (i < len) && from[i]; i++) {5454- if (le16_to_cpu(from[i]) & 0xff00) {5555- if (warn) {5454+ if (unlikely(le16_to_cpu(from[i]) & 0xff00)) {5555+ to[i] = '?';5656+ if (unlikely(warn)) {5657 warn--;5758 warn_again--;5859 printk(KERN_ERR···6261 printk(KERN_ERR6362 "mount with iocharset=utf8 to access\n");6463 }6565- to[i] = '?';6464+6665 }6766 else6867 to[i] = (char) (le16_to_cpu(from[i]));
-340
fs/jfs/jfs_xtree.c
···135135static int xtRelink(tid_t tid, struct inode *ip, xtpage_t * fp);136136#endif /* _STILL_TO_PORT */137137138138-/* External references */139139-140140-/*141141- * debug control142142- */143143-/* #define _JFS_DEBUG_XTREE 1 */144144-145145-146138/*147139 * xtLookup()148140 *···4131413941324140 return 0;41334141}41344134-41354135-41364136-#ifdef _JFS_DEBUG_XTREE41374137-/*41384138- * xtDisplayTree()41394139- *41404140- * function: traverse forward41414141- */41424142-int xtDisplayTree(struct inode *ip)41434143-{41444144- int rc = 0;41454145- struct metapage *mp;41464146- xtpage_t *p;41474147- s64 bn, pbn;41484148- int index, lastindex, v, h;41494149- xad_t *xad;41504150- struct btstack btstack;41514151- struct btframe *btsp;41524152- struct btframe *parent;41534153-41544154- printk("display B+-tree.\n");41554155-41564156- /* clear stack */41574157- btsp = btstack.stack;41584158-41594159- /*41604160- * start with root41614161- *41624162- * root resides in the inode41634163- */41644164- bn = 0;41654165- v = h = 0;41664166-41674167- /*41684168- * first access of each page:41694169- */41704170- getPage:41714171- XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);41724172- if (rc)41734173- return rc;41744174-41754175- /* process entries forward from first index */41764176- index = XTENTRYSTART;41774177- lastindex = le16_to_cpu(p->header.nextindex) - 1;41784178-41794179- if (p->header.flag & BT_INTERNAL) {41804180- /*41814181- * first access of each internal page41824182- */41834183- goto getChild;41844184- } else { /* (p->header.flag & BT_LEAF) */41854185-41864186- /*41874187- * first access of each leaf page41884188- */41894189- printf("leaf page ");41904190- xtDisplayPage(ip, bn, p);41914191-41924192- /* unpin the leaf page */41934193- XT_PUTPAGE(mp);41944194- }41954195-41964196- /*41974197- * go back up to the parent page41984198- */41994199- getParent:42004200- /* pop/restore parent entry for the current child page */42014201- if ((parent = (btsp == btstack.stack ? NULL : --btsp)) == NULL)42024202- /* current page must have been root */42034203- return;42044204-42054205- /*42064206- * parent page scan completed42074207- */42084208- if ((index = parent->index) == (lastindex = parent->lastindex)) {42094209- /* go back up to the parent page */42104210- goto getParent;42114211- }42124212-42134213- /*42144214- * parent page has entries remaining42154215- */42164216- /* get back the parent page */42174217- bn = parent->bn;42184218- /* v = parent->level; */42194219- XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);42204220- if (rc)42214221- return rc;42224222-42234223- /* get next parent entry */42244224- index++;42254225-42264226- /*42274227- * internal page: go down to child page of current entry42284228- */42294229- getChild:42304230- /* push/save current parent entry for the child page */42314231- btsp->bn = pbn = bn;42324232- btsp->index = index;42334233- btsp->lastindex = lastindex;42344234- /* btsp->level = v; */42354235- /* btsp->node = h; */42364236- ++btsp;42374237-42384238- /* get child page */42394239- xad = &p->xad[index];42404240- bn = addressXAD(xad);42414241-42424242- /*42434243- * first access of each internal entry:42444244- */42454245- /* release parent page */42464246- XT_PUTPAGE(mp);42474247-42484248- printk("traverse down 0x%lx[%d]->0x%lx\n", (ulong) pbn, index,42494249- (ulong) bn);42504250- v++;42514251- h = index;42524252-42534253- /* process the child page */42544254- goto getPage;42554255-}42564256-42574257-42584258-/*42594259- * xtDisplayPage()42604260- *42614261- * function: display page42624262- */42634263-int xtDisplayPage(struct inode *ip, s64 bn, xtpage_t * p)42644264-{42654265- int rc = 0;42664266- xad_t *xad;42674267- s64 xaddr, xoff;42684268- int xlen, i, j;42694269-42704270- /* display page control */42714271- printf("bn:0x%lx flag:0x%x nextindex:%d\n",42724272- (ulong) bn, p->header.flag,42734273- le16_to_cpu(p->header.nextindex));42744274-42754275- /* display entries */42764276- xad = &p->xad[XTENTRYSTART];42774277- for (i = XTENTRYSTART, j = 1; i < le16_to_cpu(p->header.nextindex);42784278- i++, xad++, j++) {42794279- xoff = offsetXAD(xad);42804280- xaddr = addressXAD(xad);42814281- xlen = lengthXAD(xad);42824282- printf("\t[%d] 0x%lx:0x%lx(0x%x)", i, (ulong) xoff,42834283- (ulong) xaddr, xlen);42844284-42854285- if (j == 4) {42864286- printf("\n");42874287- j = 0;42884288- }42894289- }42904290-42914291- printf("\n");42924292-}42934293-#endif /* _JFS_DEBUG_XTREE */42944294-42954295-42964296-#ifdef _JFS_WIP42974297-/*42984298- * xtGather()42994299- *43004300- * function:43014301- * traverse for allocation acquiring tlock at commit time43024302- * (vs at the time of update) logging backward top down43034303- *43044304- * note:43054305- * problem - establishing that all new allocation have been43064306- * processed both for append and random write in sparse file43074307- * at the current entry at the current subtree root page43084308- *43094309- */43104310-int xtGather(btree_t *t)43114311-{43124312- int rc = 0;43134313- xtpage_t *p;43144314- u64 bn;43154315- int index;43164316- btentry_t *e;43174317- struct btstack btstack;43184318- struct btsf *parent;43194319-43204320- /* clear stack */43214321- BT_CLR(&btstack);43224322-43234323- /*43244324- * start with root43254325- *43264326- * root resides in the inode43274327- */43284328- bn = 0;43294329- XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);43304330- if (rc)43314331- return rc;43324332-43334333- /* new root is NOT pointed by a new entry43344334- if (p->header.flag & NEW)43354335- allocate new page lock;43364336- write a NEWPAGE log;43374337- */43384338-43394339- dopage:43404340- /*43414341- * first access of each page:43424342- */43434343- /* process entries backward from last index */43444344- index = le16_to_cpu(p->header.nextindex) - 1;43454345-43464346- if (p->header.flag & BT_LEAF) {43474347- /*43484348- * first access of each leaf page43494349- */43504350- /* process leaf page entries backward */43514351- for (; index >= XTENTRYSTART; index--) {43524352- e = &p->xad[index];43534353- /*43544354- * if newpage, log NEWPAGE.43554355- *43564356- if (e->flag & XAD_NEW) {43574357- nfound =+ entry->length;43584358- update current page lock for the entry;43594359- newpage(entry);43604360- *43614361- * if moved, log move.43624362- *43634363- } else if (e->flag & XAD_MOVED) {43644364- reset flag;43654365- update current page lock for the entry;43664366- }43674367- */43684368- }43694369-43704370- /* unpin the leaf page */43714371- XT_PUTPAGE(mp);43724372-43734373- /*43744374- * go back up to the parent page43754375- */43764376- getParent:43774377- /* restore parent entry for the current child page */43784378- if ((parent = BT_POP(&btstack)) == NULL)43794379- /* current page must have been root */43804380- return 0;43814381-43824382- if ((index = parent->index) == XTENTRYSTART) {43834383- /*43844384- * parent page scan completed43854385- */43864386- /* go back up to the parent page */43874387- goto getParent;43884388- } else {43894389- /*43904390- * parent page has entries remaining43914391- */43924392- /* get back the parent page */43934393- bn = parent->bn;43944394- XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);43954395- if (rc)43964396- return -EIO;43974397-43984398- /* first subroot page which43994399- * covers all new allocated blocks44004400- * itself not new/modified.44014401- * (if modified from split of descendent,44024402- * go down path of split page)44034403-44044404- if (nfound == nnew &&44054405- !(p->header.flag & (NEW | MOD)))44064406- exit scan;44074407- */44084408-44094409- /* process parent page entries backward */44104410- index--;44114411- }44124412- } else {44134413- /*44144414- * first access of each internal page44154415- */44164416- }44174417-44184418- /*44194419- * internal page: go down to child page of current entry44204420- */44214421-44224422- /* save current parent entry for the child page */44234423- BT_PUSH(&btstack, bn, index);44244424-44254425- /* get current entry for the child page */44264426- e = &p->xad[index];44274427-44284428- /*44294429- * first access of each internal entry:44304430- */44314431- /*44324432- * if new entry, log btree_tnewentry.44334433- *44344434- if (e->flag & XAD_NEW)44354435- update parent page lock for the entry;44364436- */44374437-44384438- /* release parent page */44394439- XT_PUTPAGE(mp);44404440-44414441- /* get child page */44424442- bn = e->bn;44434443- XT_GETPAGE(ip, bn, mp, PSIZE, p, rc);44444444- if (rc)44454445- return rc;44464446-44474447- /*44484448- * first access of each non-root page:44494449- */44504450- /*44514451- * if new, log btree_newpage.44524452- *44534453- if (p->header.flag & NEW)44544454- allocate new page lock;44554455- write a NEWPAGE log (next, prev);44564456- */44574457-44584458- /* process the child page */44594459- goto dopage;44604460-44614461- out:44624462- return 0;44634463-}44644464-#endif /* _JFS_WIP */44654465-4466414244674143#ifdef CONFIG_JFS_STATISTICS44684144int jfs_xtstat_read(char *buffer, char **start, off_t offset, int length,
-6
fs/jfs/jfs_xtree.h
···131131extern int xtAppend(tid_t tid,132132 struct inode *ip, int xflag, s64 xoff, int maxblocks,133133 int *xlenp, s64 * xaddrp, int flag);134134-135135-#ifdef _JFS_DEBUG_XTREE136136-extern int xtDisplayTree(struct inode *ip);137137-extern int xtDisplayPage(struct inode *ip, s64 bn, xtpage_t * p);138138-#endif /* _JFS_DEBUG_XTREE */139139-140134#endif /* !_H_JFS_XTREE */
+3-3
fs/jfs/xattr.c
···781781 if (IS_RDONLY(inode))782782 return -EROFS;783783784784- if (IS_IMMUTABLE(inode) || IS_APPEND(inode) || S_ISLNK(inode->i_mode))784784+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode))785785 return -EPERM;786786787787 if(strncmp(name, XATTR_SYSTEM_PREFIX, XATTR_SYSTEM_PREFIX_LEN) == 0)···790790 */791791 return can_set_system_xattr(inode, name, value, value_len);792792793793- if(strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) != 0)793793+ if(strncmp(name, XATTR_TRUSTED_PREFIX, XATTR_TRUSTED_PREFIX_LEN) == 0)794794 return (capable(CAP_SYS_ADMIN) ? 0 : -EPERM);795795796796#ifdef CONFIG_JFS_SECURITY797797 if (strncmp(name, XATTR_SECURITY_PREFIX, XATTR_SECURITY_PREFIX_LEN)798798- != 0)798798+ == 0)799799 return 0; /* Leave it to the security module */800800#endif801801
···11ToDo/Notes:22 - Find and fix bugs.33- - Checkpoint or disable the user space journal ($UsnJrnl).43 - In between ntfs_prepare/commit_write, need exclusion between55- simultaneous file extensions. Need perhaps an NInoResizeUnderway()66- flag which we can set in ntfs_prepare_write() and clear again in77- ntfs_commit_write(). Just have to be careful in readpage/writepage,88- as well as in truncate, that we play nice... We might need to have99- a data_size field in the ntfs_inode to store the real attribute1010- length. Also need to be careful with initialized_size extention in44+ simultaneous file extensions. This is given to us by holding i_sem55+ on the inode. The only places in the kernel when a file is resized66+ are prepare/commit write and truncate for both of which i_sem is77+ held. Just have to be careful in readpage/writepage and all other88+ helpers not running under i_sem that we play nice...99+ Also need to be careful with initialized_size extention in1110 ntfs_prepare_write. Basically, just be _very_ careful in this code...1212- OTOH, perhaps i_sem, which is held accross generic_file_write is1313- sufficient for synchronisation here. We then just need to make sure1414- ntfs_readpage/writepage/truncate interoperate properly with us.1515- UPDATE: The above is all ok as it is due to i_sem held. The only1616- thing that needs to be checked is ntfs_writepage() which does not1717- hold i_sem. It cannot change i_size but it needs to cope with a1818- concurrent i_size change.1111+ UPDATE: The only things that need to be checked are read/writepage1212+ which do not hold i_sem. Note writepage cannot change i_size but it1313+ needs to cope with a concurrent i_size change, just like readpage.1414+ Also both need to cope with concurrent changes to the other sizes,1515+ i.e. initialized/allocated/compressed size, as well.1916 - Implement mft.c::sync_mft_mirror_umount(). We currently will just2017 leave the volume dirty on umount if the final iput(vol->mft_ino)2118 causes a write of any mirrored mft records due to the mft mirror···2225 - Enable the code for setting the NT4 compatibility flag when we start2326 making NTFS 1.2 specific modifications.24272525-2.1.23-WIP2828+2.1.23 - Implement extension of resident files and make writing safe as well as2929+ many bug fixes, cleanups, and enhancements...26302731 - Add printk rate limiting for ntfs_warning() and ntfs_error() when2832 compiled without debug. This avoids a possible denial of service2933 attack. Thanks to Carl-Daniel Hailfinger from SuSE for pointing this3034 out.3535+ - Fix compilation warnings on ia64. (Randy Dunlap)3636+ - Use i_size_{read,write}() instead of reading i_size by hand and cache3737+ the value where apropriate.3838+ - Add size_lock to the ntfs_inode structure. This is an rw spinlock3939+ and it locks against access to the inode sizes. Note, ->size_lock4040+ is also accessed from irq context so you must use the _irqsave and4141+ _irqrestore lock and unlock functions, respectively. Protect all4242+ accesses to allocated_size, initialized_size, and compressed_size.4343+ - Minor optimization to fs/ntfs/super.c::ntfs_statfs() and its helpers.4444+ - Implement extension of resident files in the regular file write code4545+ paths (fs/ntfs/aops.c::ntfs_{prepare,commit}_write()). At present4646+ this only works until the data attribute becomes too big for the mft4747+ record after which we abort the write returning -EOPNOTSUPP from4848+ ntfs_prepare_write().4949+ - Add disable_sparse mount option together with a per volume sparse5050+ enable bit which is set appropriately and a per inode sparse disable5151+ bit which is preset on some system file inodes as appropriate.5252+ - Enforce that sparse support is disabled on NTFS volumes pre 3.0.5353+ - Fix a bug in fs/ntfs/runlist.c::ntfs_mapping_pairs_decompress() in5454+ the creation of the unmapped runlist element for the base attribute5555+ extent.5656+ - Split ntfs_map_runlist() into ntfs_map_runlist() and a non-locking5757+ helper ntfs_map_runlist_nolock() which is used by ntfs_map_runlist().5858+ This allows us to map runlist fragments with the runlist lock already5959+ held without having to drop and reacquire it around the call. Adapt6060+ all callers.6161+ - Change ntfs_find_vcn() to ntfs_find_vcn_nolock() which takes a locked6262+ runlist. This allows us to find runlist elements with the runlist6363+ lock already held without having to drop and reacquire it around the6464+ call. Adapt all callers.6565+ - Change time to u64 in time.h::ntfs2utc() as it otherwise generates a6666+ warning in the do_div() call on sparc32. Thanks to Meelis Roos for6767+ the report and analysis of the warning.6868+ - Fix a nasty runlist merge bug when merging two holes.6969+ - Set the ntfs_inode->allocated_size to the real allocated size in the7070+ mft record for resident attributes (fs/ntfs/inode.c).7171+ - Small readability cleanup to use "a" instead of "ctx->attr"7272+ everywhere (fs/ntfs/inode.c).7373+ - Make fs/ntfs/namei.c::ntfs_get_{parent,dentry} static and move the7474+ definition of ntfs_export_ops from fs/ntfs/super.c to namei.c. Also,7575+ declare ntfs_export_ops in fs/ntfs/ntfs.h.7676+ - Correct sparse file handling. The compressed values need to be7777+ checked and set in the ntfs inode as done for compressed files and7878+ the compressed size needs to be used for vfs inode->i_blocks instead7979+ of the allocated size, again, as done for compressed files.8080+ - Add AT_EA in addition to AT_DATA to whitelist for being allowed to be8181+ non-resident in fs/ntfs/attrib.c::ntfs_attr_can_be_non_resident().8282+ - Add fs/ntfs/attrib.c::ntfs_attr_vcn_to_lcn_nolock() used by the new8383+ write code.8484+ - Fix bug in fs/ntfs/attrib.c::ntfs_find_vcn_nolock() where after8585+ dropping the read lock and taking the write lock we were not checking8686+ whether someone else did not already do the work we wanted to do.8787+ - Rename fs/ntfs/attrib.c::ntfs_find_vcn_nolock() to8888+ ntfs_attr_find_vcn_nolock() and update all callers.8989+ - Add fs/ntfs/attrib.[hc]::ntfs_attr_make_non_resident().9090+ - Fix sign of various error return values to be negative in9191+ fs/ntfs/lcnalloc.c.9292+ - Modify ->readpage and ->writepage (fs/ntfs/aops.c) so they detect and9393+ handle the case where an attribute is converted from resident to9494+ non-resident by a concurrent file write.9595+ - Remove checks for NULL before calling kfree() since kfree() does the9696+ checking itself. (Jesper Juhl)9797+ - Some utilities modify the boot sector but do not update the checksum.9898+ Thus, relax the checking in fs/ntfs/super.c::is_boot_sector_ntfs() to9999+ only emit a warning when the checksum is incorrect rather than100100+ refusing the mount. Thanks to Bernd Casimir for pointing this101101+ problem out.102102+ - Update attribute definition handling.103103+ - Add NTFS_MAX_CLUSTER_SIZE and NTFS_MAX_PAGES_PER_CLUSTER constants.104104+ - Use NTFS_MAX_CLUSTER_SIZE in super.c instead of hard coding 0x10000.105105+ - Use MAX_BUF_PER_PAGE instead of variable sized array allocation for106106+ better code generation and one less sparse warning in fs/ntfs/aops.c.107107+ - Remove spurious void pointer casts from fs/ntfs/. (Pekka Enberg)108108+ - Use C99 style structure initialization after memory allocation where109109+ possible (fs/ntfs/{attrib.c,index.c,super.c}). Thanks to Al Viro and110110+ Pekka Enberg.111111+ - Stamp the transaction log ($UsnJrnl), aka user space journal, if it112112+ is active on the volume and we are mounting read-write or remounting113113+ from read-only to read-write.114114+ - Fix a bug in address space operations error recovery code paths where115115+ if the runlist was not mapped at all and a mapping error occured we116116+ would leave the runlist locked on exit to the function so that the117117+ next access to the same file would try to take the lock and deadlock.118118+ - Detect the case when Windows has been suspended to disk on the volume119119+ to be mounted and if this is the case do not allow (re)mounting120120+ read-write. This is done by parsing hiberfil.sys if present.121121+ - Fix several occurences of a bug where we would perform 'var & ~const'122122+ with a 64-bit variable and a int, i.e. 32-bit, constant. This causes123123+ the higher order 32-bits of the 64-bit variable to be zeroed. To fix124124+ this cast the 'const' to the same 64-bit type as 'var'.125125+ - Change the runlist terminator of the newly allocated cluster(s) to126126+ LCN_ENOENT in ntfs_attr_make_non_resident(). Otherwise the runlist127127+ code gets confused.128128+ - Add an extra parameter @last_vcn to ntfs_get_size_for_mapping_pairs()129129+ and ntfs_mapping_pairs_build() to allow the runlist encoding to be130130+ partial which is desirable when filling holes in sparse attributes.131131+ Update all callers.132132+ - Change ntfs_map_runlist_nolock() to only decompress the mapping pairs133133+ if the requested vcn is inside it. Otherwise we get into problems134134+ when we try to map an out of bounds vcn because we then try to map135135+ the already mapped runlist fragment which causes136136+ ntfs_mapping_pairs_decompress() to fail and return error. Update137137+ ntfs_attr_find_vcn_nolock() accordingly.138138+ - Fix a nasty deadlock that appeared in recent kernels.139139+ The situation: VFS inode X on a mounted ntfs volume is dirty. For140140+ same inode X, the ntfs_inode is dirty and thus corresponding on-disk141141+ inode, i.e. mft record, which is in a dirty PAGE_CACHE_PAGE belonging142142+ to the table of inodes, i.e. $MFT, inode 0.143143+ What happens:144144+ Process 1: sys_sync()/umount()/whatever... calls145145+ __sync_single_inode() for $MFT -> do_writepages() -> write_page for146146+ the dirty page containing the on-disk inode X, the page is now locked147147+ -> ntfs_write_mst_block() which clears PageUptodate() on the page to148148+ prevent anyone else getting hold of it whilst it does the write out.149149+ This is necessary as the on-disk inode needs "fixups" applied before150150+ the write to disk which are removed again after the write and151151+ PageUptodate is then set again. It then analyses the page looking152152+ for dirty on-disk inodes and when it finds one it calls153153+ ntfs_may_write_mft_record() to see if it is safe to write this154154+ on-disk inode. This then calls ilookup5() to check if the155155+ corresponding VFS inode is in icache(). This in turn calls ifind()156156+ which waits on the inode lock via wait_on_inode whilst holding the157157+ global inode_lock.158158+ Process 2: pdflush results in a call to __sync_single_inode for the159159+ same VFS inode X on the ntfs volume. This locks the inode (I_LOCK)160160+ then calls write-inode -> ntfs_write_inode -> map_mft_record() ->161161+ read_cache_page() for the page (in page cache of table of inodes162162+ $MFT, inode 0) containing the on-disk inode. This page has163163+ PageUptodate() clear because of Process 1 (see above) so164164+ read_cache_page() blocks when it tries to take the page lock for the165165+ page so it can call ntfs_read_page().166166+ Thus Process 1 is holding the page lock on the page containing the167167+ on-disk inode X and it is waiting on the inode X to be unlocked in168168+ ifind() so it can write the page out and then unlock the page.169169+ And Process 2 is holding the inode lock on inode X and is waiting for170170+ the page to be unlocked so it can call ntfs_readpage() or discover171171+ that Process 1 set PageUptodate() again and use the page.172172+ Thus we have a deadlock due to ifind() waiting on the inode lock.173173+ The solution: The fix is to use the newly introduced174174+ ilookup5_nowait() which does not wait on the inode's lock and hence175175+ avoids the deadlock. This is safe as we do not care about the VFS176176+ inode and only use the fact that it is in the VFS inode cache and the177177+ fact that the vfs and ntfs inodes are one struct in memory to find178178+ the ntfs inode in memory if present. Also, the ntfs inode has its179179+ own locking so it does not matter if the vfs inode is locked.31180321812.1.22 - Many bug and race fixes and error handling improvements.33182···11801037 - Further runlist merging work. (Richard Russon)11811038 - Backwards compatibility for gcc-2.95. (Richard Russon)11821039 - Update to kernel 2.5.5-pre1 and rediff the now tiny patch.11831183- - Convert to new file system declaration using ->ntfs_get_sb() and10401040+ - Convert to new filesystem declaration using ->ntfs_get_sb() and11841041 replacing ntfs_read_super() with ntfs_fill_super().11851042 - Set s_maxbytes to MAX_LFS_FILESIZE to avoid page cache page index11861043 overflow on 32-bit architectures.···14761333 The driver is now actually useful! Yey. (-: It undoubtedly has got bugs14771334 though and it doesn't implement accesssing compressed files yet. Also,14781335 accessing files with attribute list attributes is not implemented yet14791479- either. But for small or simple file systems it should work and allow13361336+ either. But for small or simple filesystems it should work and allow14801337 you to list directories, use stat on directory entries and the file14811338 system, open, read, mmap and llseek around in files. A big mile stone14821339 has been reached!···14841341tng-0.0.0 - Initial version tag.1485134214861343 Initial driver implementation. The driver can mount and umount simple14871487- NTFS file systems (i.e. ones without attribute lists in the system13441344+ NTFS filesystems (i.e. ones without attribute lists in the system14881345 files). If the mount fails there might be problems in the error handling14891346 code paths, so be warned. Otherwise it seems to be loading the system14901347 files nicely and the mft record read mapping/unmapping seems to be
···22 * aops.c - NTFS kernel address space operations and page cache handling.33 * Part of the Linux-NTFS project.44 *55- * Copyright (c) 2001-2004 Anton Altaparmakov55+ * Copyright (c) 2001-2005 Anton Altaparmakov66 * Copyright (c) 2002 Richard Russon77 *88 * This program/include file is free software; you can redistribute it and/or···6666 ni = NTFS_I(page->mapping->host);67676868 if (likely(uptodate)) {6969- s64 file_ofs;6969+ s64 file_ofs, initialized_size;70707171 set_buffer_uptodate(bh);72727373 file_ofs = ((s64)page->index << PAGE_CACHE_SHIFT) +7474 bh_offset(bh);7575+ read_lock_irqsave(&ni->size_lock, flags);7676+ initialized_size = ni->initialized_size;7777+ read_unlock_irqrestore(&ni->size_lock, flags);7578 /* Check for the current buffer head overflowing. */7676- if (file_ofs + bh->b_size > ni->initialized_size) {7979+ if (file_ofs + bh->b_size > initialized_size) {7780 char *addr;7881 int ofs = 0;79828080- if (file_ofs < ni->initialized_size)8181- ofs = ni->initialized_size - file_ofs;8383+ if (file_ofs < initialized_size)8484+ ofs = initialized_size - file_ofs;8285 addr = kmap_atomic(page, KM_BIO_SRC_IRQ);8386 memset(addr + bh_offset(bh) + ofs, 0, bh->b_size - ofs);8487 flush_dcache_page(page);···135132 i * rec_size), rec_size);136133 flush_dcache_page(page);137134 kunmap_atomic(addr, KM_BIO_SRC_IRQ);138138- if (likely(!PageError(page) && page_uptodate))135135+ if (likely(page_uptodate && !PageError(page)))139136 SetPageUptodate(page);140137 }141138 unlock_page(page);···171168 runlist_element *rl;172169 struct buffer_head *bh, *head, *arr[MAX_BUF_PER_PAGE];173170 sector_t iblock, lblock, zblock;171171+ unsigned long flags;174172 unsigned int blocksize, vcn_ofs;175173 int i, nr;176174 unsigned char blocksize_bits;···194190 }195191196192 iblock = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits);193193+ read_lock_irqsave(&ni->size_lock, flags);197194 lblock = (ni->allocated_size + blocksize - 1) >> blocksize_bits;198195 zblock = (ni->initialized_size + blocksize - 1) >> blocksize_bits;196196+ read_unlock_irqrestore(&ni->size_lock, flags);199197200198 /* Loop through all the buffers in the page. */201199 rl = NULL;···264258 goto lock_retry_remap;265259 rl = NULL;266260 lcn = err;267267- }261261+ } else if (!rl)262262+ up_read(&ni->runlist.lock);268263 /* Hard error, zero out region. */269264 bh->b_blocknr = -1;270265 SetPageError(page);···348341 */349342static int ntfs_readpage(struct file *file, struct page *page)350343{351351- loff_t i_size;352344 ntfs_inode *ni, *base_ni;353345 u8 *kaddr;354346 ntfs_attr_search_ctx *ctx;355347 MFT_RECORD *mrec;348348+ unsigned long flags;356349 u32 attr_len;357350 int err = 0;358351352352+retry_readpage:359353 BUG_ON(!PageLocked(page));360354 /*361355 * This can potentially happen because we clear PageUptodate() during···391383 * Attribute is resident, implying it is not compressed or encrypted.392384 * This also means the attribute is smaller than an mft record and393385 * hence smaller than a page, so can simply zero out any pages with394394- * index above 0. We can also do this if the file size is 0.386386+ * index above 0.395387 */396396- if (unlikely(page->index > 0 || !i_size_read(VFS_I(ni)))) {388388+ if (unlikely(page->index > 0)) {397389 kaddr = kmap_atomic(page, KM_USER0);398390 memset(kaddr, 0, PAGE_CACHE_SIZE);399391 flush_dcache_page(page);···410402 err = PTR_ERR(mrec);411403 goto err_out;412404 }405405+ /*406406+ * If a parallel write made the attribute non-resident, drop the mft407407+ * record and retry the readpage.408408+ */409409+ if (unlikely(NInoNonResident(ni))) {410410+ unmap_mft_record(base_ni);411411+ goto retry_readpage;412412+ }413413 ctx = ntfs_attr_get_search_ctx(base_ni, mrec);414414 if (unlikely(!ctx)) {415415 err = -ENOMEM;···428412 if (unlikely(err))429413 goto put_unm_err_out;430414 attr_len = le32_to_cpu(ctx->attr->data.resident.value_length);431431- i_size = i_size_read(VFS_I(ni));432432- if (unlikely(attr_len > i_size))433433- attr_len = i_size;415415+ read_lock_irqsave(&ni->size_lock, flags);416416+ if (unlikely(attr_len > ni->initialized_size))417417+ attr_len = ni->initialized_size;418418+ read_unlock_irqrestore(&ni->size_lock, flags);434419 kaddr = kmap_atomic(page, KM_USER0);435420 /* Copy the data to the page. */436421 memcpy(kaddr, (u8*)ctx->attr +···480463{481464 VCN vcn;482465 LCN lcn;466466+ s64 initialized_size;467467+ loff_t i_size;483468 sector_t block, dblock, iblock;484469 struct inode *vi;485470 ntfs_inode *ni;486471 ntfs_volume *vol;487472 runlist_element *rl;488473 struct buffer_head *bh, *head;474474+ unsigned long flags;489475 unsigned int blocksize, vcn_ofs;490476 int err;491477 BOOL need_end_writeback;···530510 /* The first block in the page. */531511 block = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits);532512513513+ read_lock_irqsave(&ni->size_lock, flags);514514+ i_size = i_size_read(vi);515515+ initialized_size = ni->initialized_size;516516+ read_unlock_irqrestore(&ni->size_lock, flags);517517+533518 /* The first out of bounds block for the data size. */534534- dblock = (vi->i_size + blocksize - 1) >> blocksize_bits;519519+ dblock = (i_size + blocksize - 1) >> blocksize_bits;535520536521 /* The last (fully or partially) initialized block. */537537- iblock = ni->initialized_size >> blocksize_bits;522522+ iblock = initialized_size >> blocksize_bits;538523539524 /*540525 * Be very careful. We have no exclusion from __set_page_dirty_buffers···584559585560 /* Make sure we have enough initialized size. */586561 if (unlikely((block >= iblock) &&587587- (ni->initialized_size < vi->i_size))) {562562+ (initialized_size < i_size))) {588563 /*589564 * If this page is fully outside initialized size, zero590565 * out all pages between the current initialized size···691666 goto lock_retry_remap;692667 rl = NULL;693668 lcn = err;694694- }669669+ } else if (!rl)670670+ up_read(&ni->runlist.lock);695671 /* Failed to map the buffer, even after retrying. */696672 bh->b_blocknr = -1;697673 ntfs_error(vol->sb, "Failed to write to inode 0x%lx, "···827801 ntfs_inode *ni = NTFS_I(vi);828802 ntfs_volume *vol = ni->vol;829803 u8 *kaddr;830830- unsigned char bh_size_bits = vi->i_blkbits;831831- unsigned int bh_size = 1 << bh_size_bits;832804 unsigned int rec_size = ni->itype.index.block_size;833805 ntfs_inode *locked_nis[PAGE_CACHE_SIZE / rec_size];834806 struct buffer_head *bh, *head, *tbh, *rec_start_bh;835835- int max_bhs = PAGE_CACHE_SIZE / bh_size;836836- struct buffer_head *bhs[max_bhs];807807+ struct buffer_head *bhs[MAX_BUF_PER_PAGE];837808 runlist_element *rl;838838- int i, nr_locked_nis, nr_recs, nr_bhs, bhs_per_rec, err, err2;839839- unsigned rec_size_bits;809809+ int i, nr_locked_nis, nr_recs, nr_bhs, max_bhs, bhs_per_rec, err, err2;810810+ unsigned bh_size, rec_size_bits;840811 BOOL sync, is_mft, page_is_dirty, rec_is_dirty;812812+ unsigned char bh_size_bits;841813842814 ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index "843815 "0x%lx.", vi->i_ino, ni->type, page->index);···850826 */851827 BUG_ON(!(is_mft || S_ISDIR(vi->i_mode) ||852828 (NInoAttr(ni) && ni->type == AT_INDEX_ALLOCATION)));829829+ bh_size_bits = vi->i_blkbits;830830+ bh_size = 1 << bh_size_bits;831831+ max_bhs = PAGE_CACHE_SIZE / bh_size;853832 BUG_ON(!max_bhs);833833+ BUG_ON(max_bhs > MAX_BUF_PER_PAGE);854834855835 /* Were we called for sync purposes? */856836 sync = (wbc->sync_mode == WB_SYNC_ALL);···874846 (PAGE_CACHE_SHIFT - bh_size_bits);875847876848 /* The first out of bounds block for the data size. */877877- dblock = (vi->i_size + bh_size - 1) >> bh_size_bits;849849+ dblock = (i_size_read(vi) + bh_size - 1) >> bh_size_bits;878850879851 rl = NULL;880852 err = err2 = nr_bhs = nr_recs = nr_locked_nis = 0;···886858 if (likely(block < rec_block)) {887859 if (unlikely(block >= dblock)) {888860 clear_buffer_dirty(bh);861861+ set_buffer_uptodate(bh);889862 continue;890863 }891864 /*···967938 if (err2 == -ENOMEM)968939 page_is_dirty = TRUE;969940 lcn = err2;970970- } else941941+ } else {971942 err2 = -EIO;943943+ if (!rl)944944+ up_read(&ni->runlist.lock);945945+ }972946 /* Hard error. Abort writing this record. */973947 if (!err || err == -ENOMEM)974948 err = err2;···981949 "attribute type 0x%x) because "982950 "its location on disk could "983951 "not be determined (error "984984- "code %lli).", (s64)block <<952952+ "code %lli).",953953+ (long long)block <<985954 bh_size_bits >>986955 vol->mft_record_size_bits,987956 ni->mft_no, ni->type,···12561223static int ntfs_writepage(struct page *page, struct writeback_control *wbc)12571224{12581225 loff_t i_size;12591259- struct inode *vi;12601260- ntfs_inode *ni, *base_ni;12261226+ struct inode *vi = page->mapping->host;12271227+ ntfs_inode *base_ni = NULL, *ni = NTFS_I(vi);12611228 char *kaddr;12621262- ntfs_attr_search_ctx *ctx;12631263- MFT_RECORD *m;12291229+ ntfs_attr_search_ctx *ctx = NULL;12301230+ MFT_RECORD *m = NULL;12641231 u32 attr_len;12651232 int err;1266123312341234+retry_writepage:12671235 BUG_ON(!PageLocked(page));12681268-12691269- vi = page->mapping->host;12701236 i_size = i_size_read(vi);12711271-12721237 /* Is the page fully outside i_size? (truncate in progress) */12731238 if (unlikely(page->index >= (i_size + PAGE_CACHE_SIZE - 1) >>12741239 PAGE_CACHE_SHIFT)) {···12791248 ntfs_debug("Write outside i_size - truncated?");12801249 return 0;12811250 }12821282- ni = NTFS_I(vi);12831283-12841251 /* NInoNonResident() == NInoIndexAllocPresent() */12851252 if (NInoNonResident(ni)) {12861253 /*···13551326 ctx = NULL;13561327 goto err_out;13571328 }13291329+ /*13301330+ * If a parallel write made the attribute non-resident, drop the mft13311331+ * record and retry the writepage.13321332+ */13331333+ if (unlikely(NInoNonResident(ni))) {13341334+ unmap_mft_record(base_ni);13351335+ goto retry_writepage;13361336+ }13581337 ctx = ntfs_attr_get_search_ctx(base_ni, m);13591338 if (unlikely(!ctx)) {13601339 err = -ENOMEM;···14041367 */1405136814061369 attr_len = le32_to_cpu(ctx->attr->data.resident.value_length);14071407- i_size = i_size_read(VFS_I(ni));14081408- kaddr = kmap_atomic(page, KM_USER0);13701370+ i_size = i_size_read(vi);14091371 if (unlikely(attr_len > i_size)) {14101410- /* Zero out of bounds area in the mft record. */14111411- memset((u8*)ctx->attr + le16_to_cpu(14121412- ctx->attr->data.resident.value_offset) +14131413- i_size, 0, attr_len - i_size);14141372 attr_len = i_size;13731373+ ctx->attr->data.resident.value_length = cpu_to_le32(attr_len);14151374 }13751375+ kaddr = kmap_atomic(page, KM_USER0);14161376 /* Copy the data from the page to the mft record. */14171377 memcpy((u8*)ctx->attr +14181378 le16_to_cpu(ctx->attr->data.resident.value_offset),···14391405 err = 0;14401406 } else {14411407 ntfs_error(vi->i_sb, "Resident attribute write failed with "14421442- "error %i. Setting page error flag.", err);14081408+ "error %i.", err);14431409 SetPageError(page);14101410+ NVolSetErrors(ni->vol);14111411+ make_bad_inode(vi);14441412 }14451413 unlock_page(page);14461414 if (ctx)···14611425{14621426 VCN vcn;14631427 LCN lcn;14281428+ s64 initialized_size;14291429+ loff_t i_size;14641430 sector_t block, ablock, iblock;14651431 struct inode *vi;14661432 ntfs_inode *ni;14671433 ntfs_volume *vol;14681434 runlist_element *rl;14691435 struct buffer_head *bh, *head, *wait[2], **wait_bh = wait;14361436+ unsigned long flags;14701437 unsigned int vcn_ofs, block_start, block_end, blocksize;14711438 int err;14721439 BOOL is_retry;···15011462 /* The first block in the page. */15021463 block = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits);1503146414651465+ read_lock_irqsave(&ni->size_lock, flags);15041466 /*15051505- * The first out of bounds block for the allocated size. No need to14671467+ * The first out of bounds block for the allocated size. No need to15061468 * round up as allocated_size is in multiples of cluster size and the15071469 * minimum cluster size is 512 bytes, which is equal to the smallest15081470 * blocksize.15091471 */15101472 ablock = ni->allocated_size >> blocksize_bits;14731473+ i_size = i_size_read(vi);14741474+ initialized_size = ni->initialized_size;14751475+ read_unlock_irqrestore(&ni->size_lock, flags);1511147615121477 /* The last (fully or partially) initialized block. */15131513- iblock = ni->initialized_size >> blocksize_bits;14781478+ iblock = initialized_size >> blocksize_bits;1514147915151480 /* Loop through all the buffers in the page. */15161481 block_start = 0;···15611518 * request, i.e. block < ablock is true.15621519 */15631520 if (unlikely((block >= iblock) &&15641564- (ni->initialized_size < vi->i_size))) {15211521+ (initialized_size < i_size))) {15651522 /*15661523 * If this page is fully outside initialized size, zero15671524 * out all pages between the current initialized size···16651622 "not supported yet. "16661623 "Sorry.");16671624 err = -EOPNOTSUPP;16251625+ if (!rl)16261626+ up_read(&ni->runlist.lock);16681627 goto err_out;16691628 } else if (!is_retry &&16701629 lcn == LCN_RL_NOT_MAPPED) {···16811636 goto lock_retry_remap;16821637 rl = NULL;16831638 lcn = err;16841684- }16391639+ } else if (!rl)16401640+ up_read(&ni->runlist.lock);16851641 /*16861642 * Failed to map the buffer, even after16871643 * retrying.···18431797 unsigned from, unsigned to)18441798{18451799 s64 new_size;18001800+ loff_t i_size;18461801 struct inode *vi = page->mapping->host;18471802 ntfs_inode *base_ni = NULL, *ni = NTFS_I(vi);18481803 ntfs_volume *vol = ni->vol;···19151868 BUG_ON(page_has_buffers(page));19161869 new_size = ((s64)page->index << PAGE_CACHE_SHIFT) + to;19171870 /* If we do not need to resize the attribute allocation we are done. */19181918- if (new_size <= vi->i_size)18711871+ if (new_size <= i_size_read(vi))19191872 goto done;19201920-19211921- // FIXME: We abort for now as this code is not safe.19221922- ntfs_error(vi->i_sb, "Changing the file size is not supported yet. "19231923- "Sorry.");19241924- return -EOPNOTSUPP;19251925-19261873 /* Map, pin, and lock the (base) mft record. */19271874 if (!NInoAttr(ni))19281875 base_ni = ni;···19451904 a = ctx->attr;19461905 /* The total length of the attribute value. */19471906 attr_len = le32_to_cpu(a->data.resident.value_length);19481948- BUG_ON(vi->i_size != attr_len);19071907+ /* Fix an eventual previous failure of ntfs_commit_write(). */19081908+ i_size = i_size_read(vi);19091909+ if (unlikely(attr_len > i_size)) {19101910+ attr_len = i_size;19111911+ a->data.resident.value_length = cpu_to_le32(attr_len);19121912+ }19131913+ /* If we do not need to resize the attribute allocation we are done. */19141914+ if (new_size <= attr_len)19151915+ goto done_unm;19491916 /* Check if new size is allowed in $AttrDef. */19501917 err = ntfs_attr_size_bounds_check(vol, ni->type, new_size);19511918 if (unlikely(err)) {···20111962 }20121963 flush_dcache_mft_record_page(ctx->ntfs_ino);20131964 mark_mft_record_dirty(ctx->ntfs_ino);19651965+done_unm:20141966 ntfs_attr_put_search_ctx(ctx);20151967 unmap_mft_record(base_ni);20161968 /*···20972047 * now we know ntfs_prepare_write() would have failed in the write20982048 * exceeds i_size case, so this will never trigger which is fine.20992049 */21002100- if (pos > vi->i_size) {20502050+ if (pos > i_size_read(vi)) {21012051 ntfs_error(vi->i_sb, "Writing beyond the existing file size is "21022052 "not supported yet. Sorry.");21032053 return -EOPNOTSUPP;···22332183 }22342184 kunmap_atomic(kaddr, KM_USER0);22352185 /* Update i_size if necessary. */22362236- if (vi->i_size < attr_len) {21862186+ if (i_size_read(vi) < attr_len) {21872187+ unsigned long flags;21882188+21892189+ write_lock_irqsave(&ni->size_lock, flags);22372190 ni->allocated_size = ni->initialized_size = attr_len;22382191 i_size_write(vi, attr_len);21922192+ write_unlock_irqrestore(&ni->size_lock, flags);22392193 }22402194 /* Mark the mft record dirty, so it gets written back. */22412195 flush_dcache_mft_record_page(ctx->ntfs_ino);
+557-99
fs/ntfs/attrib.c
···11/**22 * attrib.c - NTFS attribute operations. Part of the Linux-NTFS project.33 *44- * Copyright (c) 2001-2004 Anton Altaparmakov44+ * Copyright (c) 2001-2005 Anton Altaparmakov55 * Copyright (c) 2002 Richard Russon66 *77 * This program/include file is free software; you can redistribute it and/or···2121 */22222323#include <linux/buffer_head.h>2424+#include <linux/swap.h>24252526#include "attrib.h"2627#include "debug.h"2728#include "layout.h"2929+#include "lcnalloc.h"3030+#include "malloc.h"2831#include "mft.h"2932#include "ntfs.h"3033#include "types.h"3434+3535+/**3636+ * ntfs_map_runlist_nolock - map (a part of) a runlist of an ntfs inode3737+ * @ni: ntfs inode for which to map (part of) a runlist3838+ * @vcn: map runlist part containing this vcn3939+ *4040+ * Map the part of a runlist containing the @vcn of the ntfs inode @ni.4141+ *4242+ * Return 0 on success and -errno on error. There is one special error code4343+ * which is not an error as such. This is -ENOENT. It means that @vcn is out4444+ * of bounds of the runlist.4545+ *4646+ * Locking: - The runlist must be locked for writing.4747+ * - This function modifies the runlist.4848+ */4949+int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn)5050+{5151+ VCN end_vcn;5252+ ntfs_inode *base_ni;5353+ MFT_RECORD *m;5454+ ATTR_RECORD *a;5555+ ntfs_attr_search_ctx *ctx;5656+ runlist_element *rl;5757+ int err = 0;5858+5959+ ntfs_debug("Mapping runlist part containing vcn 0x%llx.",6060+ (unsigned long long)vcn);6161+ if (!NInoAttr(ni))6262+ base_ni = ni;6363+ else6464+ base_ni = ni->ext.base_ntfs_ino;6565+ m = map_mft_record(base_ni);6666+ if (IS_ERR(m))6767+ return PTR_ERR(m);6868+ ctx = ntfs_attr_get_search_ctx(base_ni, m);6969+ if (unlikely(!ctx)) {7070+ err = -ENOMEM;7171+ goto err_out;7272+ }7373+ err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,7474+ CASE_SENSITIVE, vcn, NULL, 0, ctx);7575+ if (unlikely(err)) {7676+ if (err == -ENOENT)7777+ err = -EIO;7878+ goto err_out;7979+ }8080+ a = ctx->attr;8181+ /*8282+ * Only decompress the mapping pairs if @vcn is inside it. Otherwise8383+ * we get into problems when we try to map an out of bounds vcn because8484+ * we then try to map the already mapped runlist fragment and8585+ * ntfs_mapping_pairs_decompress() fails.8686+ */8787+ end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn) + 1;8888+ if (unlikely(!a->data.non_resident.lowest_vcn && end_vcn <= 1))8989+ end_vcn = ni->allocated_size >> ni->vol->cluster_size_bits;9090+ if (unlikely(vcn >= end_vcn)) {9191+ err = -ENOENT;9292+ goto err_out;9393+ }9494+ rl = ntfs_mapping_pairs_decompress(ni->vol, a, ni->runlist.rl);9595+ if (IS_ERR(rl))9696+ err = PTR_ERR(rl);9797+ else9898+ ni->runlist.rl = rl;9999+err_out:100100+ if (likely(ctx))101101+ ntfs_attr_put_search_ctx(ctx);102102+ unmap_mft_record(base_ni);103103+ return err;104104+}3110532106/**33107 * ntfs_map_runlist - map (a part of) a runlist of an ntfs inode···11036 *11137 * Map the part of a runlist containing the @vcn of the ntfs inode @ni.11238 *113113- * Return 0 on success and -errno on error.3939+ * Return 0 on success and -errno on error. There is one special error code4040+ * which is not an error as such. This is -ENOENT. It means that @vcn is out4141+ * of bounds of the runlist.11442 *11543 * Locking: - The runlist must be unlocked on entry and is unlocked on return.116116- * - This function takes the lock for writing and modifies the runlist.4444+ * - This function takes the runlist lock for writing and modifies the4545+ * runlist.11746 */11847int ntfs_map_runlist(ntfs_inode *ni, VCN vcn)11948{120120- ntfs_inode *base_ni;121121- ntfs_attr_search_ctx *ctx;122122- MFT_RECORD *mrec;12349 int err = 0;124124-125125- ntfs_debug("Mapping runlist part containing vcn 0x%llx.",126126- (unsigned long long)vcn);127127-128128- if (!NInoAttr(ni))129129- base_ni = ni;130130- else131131- base_ni = ni->ext.base_ntfs_ino;132132-133133- mrec = map_mft_record(base_ni);134134- if (IS_ERR(mrec))135135- return PTR_ERR(mrec);136136- ctx = ntfs_attr_get_search_ctx(base_ni, mrec);137137- if (unlikely(!ctx)) {138138- err = -ENOMEM;139139- goto err_out;140140- }141141- err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,142142- CASE_SENSITIVE, vcn, NULL, 0, ctx);143143- if (unlikely(err))144144- goto put_err_out;1455014651 down_write(&ni->runlist.lock);14752 /* Make sure someone else didn't do the work while we were sleeping. */14853 if (likely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) <=149149- LCN_RL_NOT_MAPPED)) {150150- runlist_element *rl;151151-152152- rl = ntfs_mapping_pairs_decompress(ni->vol, ctx->attr,153153- ni->runlist.rl);154154- if (IS_ERR(rl))155155- err = PTR_ERR(rl);156156- else157157- ni->runlist.rl = rl;158158- }5454+ LCN_RL_NOT_MAPPED))5555+ err = ntfs_map_runlist_nolock(ni, vcn);15956 up_write(&ni->runlist.lock);160160-161161-put_err_out:162162- ntfs_attr_put_search_ctx(ctx);163163-err_out:164164- unmap_mft_record(base_ni);16557 return err;16658}1675916860/**169169- * ntfs_find_vcn - find a vcn in the runlist described by an ntfs inode170170- * @ni: ntfs inode describing the runlist to search171171- * @vcn: vcn to find172172- * @need_write: if false, lock for reading and if true, lock for writing6161+ * ntfs_attr_vcn_to_lcn_nolock - convert a vcn into a lcn given an ntfs inode6262+ * @ni: ntfs inode of the attribute whose runlist to search6363+ * @vcn: vcn to convert6464+ * @write_locked: true if the runlist is locked for writing6565+ *6666+ * Find the virtual cluster number @vcn in the runlist of the ntfs attribute6767+ * described by the ntfs inode @ni and return the corresponding logical cluster6868+ * number (lcn).6969+ *7070+ * If the @vcn is not mapped yet, the attempt is made to map the attribute7171+ * extent containing the @vcn and the vcn to lcn conversion is retried.7272+ *7373+ * If @write_locked is true the caller has locked the runlist for writing and7474+ * if false for reading.7575+ *7676+ * Since lcns must be >= 0, we use negative return codes with special meaning:7777+ *7878+ * Return code Meaning / Description7979+ * ==========================================8080+ * LCN_HOLE Hole / not allocated on disk.8181+ * LCN_ENOENT There is no such vcn in the runlist, i.e. @vcn is out of bounds.8282+ * LCN_ENOMEM Not enough memory to map runlist.8383+ * LCN_EIO Critical error (runlist/file is corrupt, i/o error, etc).8484+ *8585+ * Locking: - The runlist must be locked on entry and is left locked on return.8686+ * - If @write_locked is FALSE, i.e. the runlist is locked for reading,8787+ * the lock may be dropped inside the function so you cannot rely on8888+ * the runlist still being the same when this function returns.8989+ */9090+LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn,9191+ const BOOL write_locked)9292+{9393+ LCN lcn;9494+ BOOL is_retry = FALSE;9595+9696+ ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.",9797+ ni->mft_no, (unsigned long long)vcn,9898+ write_locked ? "write" : "read");9999+ BUG_ON(!ni);100100+ BUG_ON(!NInoNonResident(ni));101101+ BUG_ON(vcn < 0);102102+retry_remap:103103+ /* Convert vcn to lcn. If that fails map the runlist and retry once. */104104+ lcn = ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn);105105+ if (likely(lcn >= LCN_HOLE)) {106106+ ntfs_debug("Done, lcn 0x%llx.", (long long)lcn);107107+ return lcn;108108+ }109109+ if (lcn != LCN_RL_NOT_MAPPED) {110110+ if (lcn != LCN_ENOENT)111111+ lcn = LCN_EIO;112112+ } else if (!is_retry) {113113+ int err;114114+115115+ if (!write_locked) {116116+ up_read(&ni->runlist.lock);117117+ down_write(&ni->runlist.lock);118118+ if (unlikely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) !=119119+ LCN_RL_NOT_MAPPED)) {120120+ up_write(&ni->runlist.lock);121121+ down_read(&ni->runlist.lock);122122+ goto retry_remap;123123+ }124124+ }125125+ err = ntfs_map_runlist_nolock(ni, vcn);126126+ if (!write_locked) {127127+ up_write(&ni->runlist.lock);128128+ down_read(&ni->runlist.lock);129129+ }130130+ if (likely(!err)) {131131+ is_retry = TRUE;132132+ goto retry_remap;133133+ }134134+ if (err == -ENOENT)135135+ lcn = LCN_ENOENT;136136+ else if (err == -ENOMEM)137137+ lcn = LCN_ENOMEM;138138+ else139139+ lcn = LCN_EIO;140140+ }141141+ if (lcn != LCN_ENOENT)142142+ ntfs_error(ni->vol->sb, "Failed with error code %lli.",143143+ (long long)lcn);144144+ return lcn;145145+}146146+147147+/**148148+ * ntfs_attr_find_vcn_nolock - find a vcn in the runlist of an ntfs inode149149+ * @ni: ntfs inode describing the runlist to search150150+ * @vcn: vcn to find151151+ * @write_locked: true if the runlist is locked for writing173152 *174153 * Find the virtual cluster number @vcn in the runlist described by the ntfs175154 * inode @ni and return the address of the runlist element containing the @vcn.176176- * The runlist is left locked and the caller has to unlock it. If @need_write177177- * is true, the runlist is locked for writing and if @need_write is false, the178178- * runlist is locked for reading. In the error case, the runlist is not left179179- * locked.155155+ *156156+ * If the @vcn is not mapped yet, the attempt is made to map the attribute157157+ * extent containing the @vcn and the vcn to lcn conversion is retried.158158+ *159159+ * If @write_locked is true the caller has locked the runlist for writing and160160+ * if false for reading.180161 *181162 * Note you need to distinguish between the lcn of the returned runlist element182163 * being >= 0 and LCN_HOLE. In the later case you have to return zeroes on···247118 * -ENOMEM - Not enough memory to map runlist.248119 * -EIO - Critical error (runlist/file is corrupt, i/o error, etc).249120 *250250- * Locking: - The runlist must be unlocked on entry.251251- * - On failing return, the runlist is unlocked.252252- * - On successful return, the runlist is locked. If @need_write us253253- * true, it is locked for writing. Otherwise is is locked for254254- * reading.121121+ * Locking: - The runlist must be locked on entry and is left locked on return.122122+ * - If @write_locked is FALSE, i.e. the runlist is locked for reading,123123+ * the lock may be dropped inside the function so you cannot rely on124124+ * the runlist still being the same when this function returns.255125 */256256-runlist_element *ntfs_find_vcn(ntfs_inode *ni, const VCN vcn,257257- const BOOL need_write)126126+runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn,127127+ const BOOL write_locked)258128{259129 runlist_element *rl;260130 int err = 0;261131 BOOL is_retry = FALSE;262132263263- ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, lock for %sing.",133133+ ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.",264134 ni->mft_no, (unsigned long long)vcn,265265- !need_write ? "read" : "writ");135135+ write_locked ? "write" : "read");266136 BUG_ON(!ni);267137 BUG_ON(!NInoNonResident(ni));268138 BUG_ON(vcn < 0);269269-lock_retry_remap:270270- if (!need_write)271271- down_read(&ni->runlist.lock);272272- else273273- down_write(&ni->runlist.lock);139139+retry_remap:274140 rl = ni->runlist.rl;275141 if (likely(rl && vcn >= rl[0].vcn)) {276142 while (likely(rl->length)) {277277- if (likely(vcn < rl[1].vcn)) {143143+ if (unlikely(vcn < rl[1].vcn)) {278144 if (likely(rl->lcn >= LCN_HOLE)) {279145 ntfs_debug("Done.");280146 return rl;···285161 err = -EIO;286162 }287163 }288288- if (!need_write)289289- up_read(&ni->runlist.lock);290290- else291291- up_write(&ni->runlist.lock);292164 if (!err && !is_retry) {293165 /*294166 * The @vcn is in an unmapped region, map the runlist and295167 * retry.296168 */297297- err = ntfs_map_runlist(ni, vcn);169169+ if (!write_locked) {170170+ up_read(&ni->runlist.lock);171171+ down_write(&ni->runlist.lock);172172+ if (unlikely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) !=173173+ LCN_RL_NOT_MAPPED)) {174174+ up_write(&ni->runlist.lock);175175+ down_read(&ni->runlist.lock);176176+ goto retry_remap;177177+ }178178+ }179179+ err = ntfs_map_runlist_nolock(ni, vcn);180180+ if (!write_locked) {181181+ up_write(&ni->runlist.lock);182182+ down_read(&ni->runlist.lock);183183+ }298184 if (likely(!err)) {299185 is_retry = TRUE;300300- goto lock_retry_remap;186186+ goto retry_remap;301187 }302188 /*303303- * -EINVAL and -ENOENT coming from a failed mapping attempt are304304- * equivalent to i/o errors for us as they should not happen in305305- * our code paths.189189+ * -EINVAL coming from a failed mapping attempt is equivalent190190+ * to i/o error for us as it should not happen in our code191191+ * paths.306192 */307307- if (err == -EINVAL || err == -ENOENT)193193+ if (err == -EINVAL)308194 err = -EIO;309195 } else if (!err)310196 err = -EIO;311311- ntfs_error(ni->vol->sb, "Failed with error code %i.", err);197197+ if (err != -ENOENT)198198+ ntfs_error(ni->vol->sb, "Failed with error code %i.", err);312199 return ERR_PTR(err);313200}314201···1005870static inline void ntfs_attr_init_search_ctx(ntfs_attr_search_ctx *ctx,1006871 ntfs_inode *ni, MFT_RECORD *mrec)1007872{10081008- ctx->mrec = mrec;10091009- /* Sanity checks are performed elsewhere. */10101010- ctx->attr = (ATTR_RECORD*)((u8*)mrec + le16_to_cpu(mrec->attrs_offset));10111011- ctx->is_first = TRUE;10121012- ctx->ntfs_ino = ni;10131013- ctx->al_entry = NULL;10141014- ctx->base_ntfs_ino = NULL;10151015- ctx->base_mrec = NULL;10161016- ctx->base_attr = NULL;873873+ *ctx = (ntfs_attr_search_ctx) {874874+ .mrec = mrec,875875+ /* Sanity checks are performed elsewhere. */876876+ .attr = (ATTR_RECORD*)((u8*)mrec +877877+ le16_to_cpu(mrec->attrs_offset)),878878+ .is_first = TRUE,879879+ .ntfs_ino = ni,880880+ };1017881}10188821019883/**···1078944 kmem_cache_free(ntfs_attr_ctx_cache, ctx);1079945 return;1080946}947947+948948+#ifdef NTFS_RW10819491082950/**1083951 * ntfs_attr_find_in_attrdef - find an attribute in the $AttrDef system file···11601024 * Check whether the attribute of @type on the ntfs volume @vol is allowed to11611025 * be non-resident. This information is obtained from $AttrDef system file.11621026 *11631163- * Return 0 if the attribute is allowed to be non-resident, -EPERM if not, or10271027+ * Return 0 if the attribute is allowed to be non-resident, -EPERM if not, and11641028 * -ENOENT if the attribute is not listed in $AttrDef.11651029 */11661030int ntfs_attr_can_be_non_resident(const ntfs_volume *vol, const ATTR_TYPE type)11671031{11681032 ATTR_DEF *ad;1169103311701170- /*11711171- * $DATA is always allowed to be non-resident even if $AttrDef does not11721172- * specify this in the flags of the $DATA attribute definition record.11731173- */11741174- if (type == AT_DATA)11751175- return 0;11761034 /* Find the attribute definition record in $AttrDef. */11771035 ad = ntfs_attr_find_in_attrdef(vol, type);11781036 if (unlikely(!ad))11791037 return -ENOENT;11801038 /* Check the flags and return the result. */11811181- if (ad->flags & CAN_BE_NON_RESIDENT)11821182- return 0;11831183- return -EPERM;10391039+ if (ad->flags & ATTR_DEF_RESIDENT)10401040+ return -EPERM;10411041+ return 0;11841042}1185104311861044/**···11971067 */11981068int ntfs_attr_can_be_resident(const ntfs_volume *vol, const ATTR_TYPE type)11991069{12001200- if (type != AT_INDEX_ALLOCATION && type != AT_EA)12011201- return 0;12021202- return -EPERM;10701070+ if (type == AT_INDEX_ALLOCATION || type == AT_EA)10711071+ return -EPERM;10721072+ return 0;12031073}1204107412051075/**···12471117}1248111812491119/**11201120+ * ntfs_attr_make_non_resident - convert a resident to a non-resident attribute11211121+ * @ni: ntfs inode describing the attribute to convert11221122+ *11231123+ * Convert the resident ntfs attribute described by the ntfs inode @ni to a11241124+ * non-resident one.11251125+ *11261126+ * Return 0 on success and -errno on error. The following error return codes11271127+ * are defined:11281128+ * -EPERM - The attribute is not allowed to be non-resident.11291129+ * -ENOMEM - Not enough memory.11301130+ * -ENOSPC - Not enough disk space.11311131+ * -EINVAL - Attribute not defined on the volume.11321132+ * -EIO - I/o error or other error.11331133+ * Note that -ENOSPC is also returned in the case that there is not enough11341134+ * space in the mft record to do the conversion. This can happen when the mft11351135+ * record is already very full. The caller is responsible for trying to make11361136+ * space in the mft record and trying again. FIXME: Do we need a separate11371137+ * error return code for this kind of -ENOSPC or is it always worth trying11381138+ * again in case the attribute may then fit in a resident state so no need to11391139+ * make it non-resident at all? Ho-hum... (AIA)11401140+ *11411141+ * NOTE to self: No changes in the attribute list are required to move from11421142+ * a resident to a non-resident attribute.11431143+ *11441144+ * Locking: - The caller must hold i_sem on the inode.11451145+ */11461146+int ntfs_attr_make_non_resident(ntfs_inode *ni)11471147+{11481148+ s64 new_size;11491149+ struct inode *vi = VFS_I(ni);11501150+ ntfs_volume *vol = ni->vol;11511151+ ntfs_inode *base_ni;11521152+ MFT_RECORD *m;11531153+ ATTR_RECORD *a;11541154+ ntfs_attr_search_ctx *ctx;11551155+ struct page *page;11561156+ runlist_element *rl;11571157+ u8 *kaddr;11581158+ unsigned long flags;11591159+ int mp_size, mp_ofs, name_ofs, arec_size, err, err2;11601160+ u32 attr_size;11611161+ u8 old_res_attr_flags;11621162+11631163+ /* Check that the attribute is allowed to be non-resident. */11641164+ err = ntfs_attr_can_be_non_resident(vol, ni->type);11651165+ if (unlikely(err)) {11661166+ if (err == -EPERM)11671167+ ntfs_debug("Attribute is not allowed to be "11681168+ "non-resident.");11691169+ else11701170+ ntfs_debug("Attribute not defined on the NTFS "11711171+ "volume!");11721172+ return err;11731173+ }11741174+ /*11751175+ * The size needs to be aligned to a cluster boundary for allocation11761176+ * purposes.11771177+ */11781178+ new_size = (i_size_read(vi) + vol->cluster_size - 1) &11791179+ ~(vol->cluster_size - 1);11801180+ if (new_size > 0) {11811181+ runlist_element *rl2;11821182+11831183+ /*11841184+ * Will need the page later and since the page lock nests11851185+ * outside all ntfs locks, we need to get the page now.11861186+ */11871187+ page = find_or_create_page(vi->i_mapping, 0,11881188+ mapping_gfp_mask(vi->i_mapping));11891189+ if (unlikely(!page))11901190+ return -ENOMEM;11911191+ /* Start by allocating clusters to hold the attribute value. */11921192+ rl = ntfs_cluster_alloc(vol, 0, new_size >>11931193+ vol->cluster_size_bits, -1, DATA_ZONE);11941194+ if (IS_ERR(rl)) {11951195+ err = PTR_ERR(rl);11961196+ ntfs_debug("Failed to allocate cluster%s, error code "11971197+ "%i.", (new_size >>11981198+ vol->cluster_size_bits) > 1 ? "s" : "",11991199+ err);12001200+ goto page_err_out;12011201+ }12021202+ /* Change the runlist terminator to LCN_ENOENT. */12031203+ rl2 = rl;12041204+ while (rl2->length)12051205+ rl2++;12061206+ BUG_ON(rl2->lcn != LCN_RL_NOT_MAPPED);12071207+ rl2->lcn = LCN_ENOENT;12081208+ } else {12091209+ rl = NULL;12101210+ page = NULL;12111211+ }12121212+ /* Determine the size of the mapping pairs array. */12131213+ mp_size = ntfs_get_size_for_mapping_pairs(vol, rl, 0, -1);12141214+ if (unlikely(mp_size < 0)) {12151215+ err = mp_size;12161216+ ntfs_debug("Failed to get size for mapping pairs array, error "12171217+ "code %i.", err);12181218+ goto rl_err_out;12191219+ }12201220+ down_write(&ni->runlist.lock);12211221+ if (!NInoAttr(ni))12221222+ base_ni = ni;12231223+ else12241224+ base_ni = ni->ext.base_ntfs_ino;12251225+ m = map_mft_record(base_ni);12261226+ if (IS_ERR(m)) {12271227+ err = PTR_ERR(m);12281228+ m = NULL;12291229+ ctx = NULL;12301230+ goto err_out;12311231+ }12321232+ ctx = ntfs_attr_get_search_ctx(base_ni, m);12331233+ if (unlikely(!ctx)) {12341234+ err = -ENOMEM;12351235+ goto err_out;12361236+ }12371237+ err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,12381238+ CASE_SENSITIVE, 0, NULL, 0, ctx);12391239+ if (unlikely(err)) {12401240+ if (err == -ENOENT)12411241+ err = -EIO;12421242+ goto err_out;12431243+ }12441244+ m = ctx->mrec;12451245+ a = ctx->attr;12461246+ BUG_ON(NInoNonResident(ni));12471247+ BUG_ON(a->non_resident);12481248+ /*12491249+ * Calculate new offsets for the name and the mapping pairs array.12501250+ * We assume the attribute is not compressed or sparse.12511251+ */12521252+ name_ofs = (offsetof(ATTR_REC,12531253+ data.non_resident.compressed_size) + 7) & ~7;12541254+ mp_ofs = (name_ofs + a->name_length * sizeof(ntfschar) + 7) & ~7;12551255+ /*12561256+ * Determine the size of the resident part of the now non-resident12571257+ * attribute record.12581258+ */12591259+ arec_size = (mp_ofs + mp_size + 7) & ~7;12601260+ /*12611261+ * If the page is not uptodate bring it uptodate by copying from the12621262+ * attribute value.12631263+ */12641264+ attr_size = le32_to_cpu(a->data.resident.value_length);12651265+ BUG_ON(attr_size != i_size_read(vi));12661266+ if (page && !PageUptodate(page)) {12671267+ kaddr = kmap_atomic(page, KM_USER0);12681268+ memcpy(kaddr, (u8*)a +12691269+ le16_to_cpu(a->data.resident.value_offset),12701270+ attr_size);12711271+ memset(kaddr + attr_size, 0, PAGE_CACHE_SIZE - attr_size);12721272+ kunmap_atomic(kaddr, KM_USER0);12731273+ flush_dcache_page(page);12741274+ SetPageUptodate(page);12751275+ }12761276+ /* Backup the attribute flag. */12771277+ old_res_attr_flags = a->data.resident.flags;12781278+ /* Resize the resident part of the attribute record. */12791279+ err = ntfs_attr_record_resize(m, a, arec_size);12801280+ if (unlikely(err))12811281+ goto err_out;12821282+ /*12831283+ * Convert the resident part of the attribute record to describe a12841284+ * non-resident attribute.12851285+ */12861286+ a->non_resident = 1;12871287+ /* Move the attribute name if it exists and update the offset. */12881288+ if (a->name_length)12891289+ memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset),12901290+ a->name_length * sizeof(ntfschar));12911291+ a->name_offset = cpu_to_le16(name_ofs);12921292+ /*12931293+ * FIXME: For now just clear all of these as we do not support them12941294+ * when writing.12951295+ */12961296+ a->flags &= cpu_to_le16(0xffff & ~le16_to_cpu(ATTR_IS_SPARSE |12971297+ ATTR_IS_ENCRYPTED | ATTR_COMPRESSION_MASK));12981298+ /* Setup the fields specific to non-resident attributes. */12991299+ a->data.non_resident.lowest_vcn = 0;13001300+ a->data.non_resident.highest_vcn = cpu_to_sle64((new_size - 1) >>13011301+ vol->cluster_size_bits);13021302+ a->data.non_resident.mapping_pairs_offset = cpu_to_le16(mp_ofs);13031303+ a->data.non_resident.compression_unit = 0;13041304+ memset(&a->data.non_resident.reserved, 0,13051305+ sizeof(a->data.non_resident.reserved));13061306+ a->data.non_resident.allocated_size = cpu_to_sle64(new_size);13071307+ a->data.non_resident.data_size =13081308+ a->data.non_resident.initialized_size =13091309+ cpu_to_sle64(attr_size);13101310+ /* Generate the mapping pairs array into the attribute record. */13111311+ err = ntfs_mapping_pairs_build(vol, (u8*)a + mp_ofs,13121312+ arec_size - mp_ofs, rl, 0, -1, NULL);13131313+ if (unlikely(err)) {13141314+ ntfs_debug("Failed to build mapping pairs, error code %i.",13151315+ err);13161316+ goto undo_err_out;13171317+ }13181318+ /* Setup the in-memory attribute structure to be non-resident. */13191319+ /*13201320+ * FIXME: For now just clear all of these as we do not support them13211321+ * when writing.13221322+ */13231323+ NInoClearSparse(ni);13241324+ NInoClearEncrypted(ni);13251325+ NInoClearCompressed(ni);13261326+ ni->runlist.rl = rl;13271327+ write_lock_irqsave(&ni->size_lock, flags);13281328+ ni->allocated_size = new_size;13291329+ write_unlock_irqrestore(&ni->size_lock, flags);13301330+ /*13311331+ * This needs to be last since the address space operations ->readpage13321332+ * and ->writepage can run concurrently with us as they are not13331333+ * serialized on i_sem. Note, we are not allowed to fail once we flip13341334+ * this switch, which is another reason to do this last.13351335+ */13361336+ NInoSetNonResident(ni);13371337+ /* Mark the mft record dirty, so it gets written back. */13381338+ flush_dcache_mft_record_page(ctx->ntfs_ino);13391339+ mark_mft_record_dirty(ctx->ntfs_ino);13401340+ ntfs_attr_put_search_ctx(ctx);13411341+ unmap_mft_record(base_ni);13421342+ up_write(&ni->runlist.lock);13431343+ if (page) {13441344+ set_page_dirty(page);13451345+ unlock_page(page);13461346+ mark_page_accessed(page);13471347+ page_cache_release(page);13481348+ }13491349+ ntfs_debug("Done.");13501350+ return 0;13511351+undo_err_out:13521352+ /* Convert the attribute back into a resident attribute. */13531353+ a->non_resident = 0;13541354+ /* Move the attribute name if it exists and update the offset. */13551355+ name_ofs = (offsetof(ATTR_RECORD, data.resident.reserved) +13561356+ sizeof(a->data.resident.reserved) + 7) & ~7;13571357+ if (a->name_length)13581358+ memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset),13591359+ a->name_length * sizeof(ntfschar));13601360+ mp_ofs = (name_ofs + a->name_length * sizeof(ntfschar) + 7) & ~7;13611361+ a->name_offset = cpu_to_le16(name_ofs);13621362+ arec_size = (mp_ofs + attr_size + 7) & ~7;13631363+ /* Resize the resident part of the attribute record. */13641364+ err2 = ntfs_attr_record_resize(m, a, arec_size);13651365+ if (unlikely(err2)) {13661366+ /*13671367+ * This cannot happen (well if memory corruption is at work it13681368+ * could happen in theory), but deal with it as well as we can.13691369+ * If the old size is too small, truncate the attribute,13701370+ * otherwise simply give it a larger allocated size.13711371+ * FIXME: Should check whether chkdsk complains when the13721372+ * allocated size is much bigger than the resident value size.13731373+ */13741374+ arec_size = le32_to_cpu(a->length);13751375+ if ((mp_ofs + attr_size) > arec_size) {13761376+ err2 = attr_size;13771377+ attr_size = arec_size - mp_ofs;13781378+ ntfs_error(vol->sb, "Failed to undo partial resident "13791379+ "to non-resident attribute "13801380+ "conversion. Truncating inode 0x%lx, "13811381+ "attribute type 0x%x from %i bytes to "13821382+ "%i bytes to maintain metadata "13831383+ "consistency. THIS MEANS YOU ARE "13841384+ "LOSING %i BYTES DATA FROM THIS %s.",13851385+ vi->i_ino,13861386+ (unsigned)le32_to_cpu(ni->type),13871387+ err2, attr_size, err2 - attr_size,13881388+ ((ni->type == AT_DATA) &&13891389+ !ni->name_len) ? "FILE": "ATTRIBUTE");13901390+ write_lock_irqsave(&ni->size_lock, flags);13911391+ ni->initialized_size = attr_size;13921392+ i_size_write(vi, attr_size);13931393+ write_unlock_irqrestore(&ni->size_lock, flags);13941394+ }13951395+ }13961396+ /* Setup the fields specific to resident attributes. */13971397+ a->data.resident.value_length = cpu_to_le32(attr_size);13981398+ a->data.resident.value_offset = cpu_to_le16(mp_ofs);13991399+ a->data.resident.flags = old_res_attr_flags;14001400+ memset(&a->data.resident.reserved, 0,14011401+ sizeof(a->data.resident.reserved));14021402+ /* Copy the data from the page back to the attribute value. */14031403+ if (page) {14041404+ kaddr = kmap_atomic(page, KM_USER0);14051405+ memcpy((u8*)a + mp_ofs, kaddr, attr_size);14061406+ kunmap_atomic(kaddr, KM_USER0);14071407+ }14081408+ /* Setup the allocated size in the ntfs inode in case it changed. */14091409+ write_lock_irqsave(&ni->size_lock, flags);14101410+ ni->allocated_size = arec_size - mp_ofs;14111411+ write_unlock_irqrestore(&ni->size_lock, flags);14121412+ /* Mark the mft record dirty, so it gets written back. */14131413+ flush_dcache_mft_record_page(ctx->ntfs_ino);14141414+ mark_mft_record_dirty(ctx->ntfs_ino);14151415+err_out:14161416+ if (ctx)14171417+ ntfs_attr_put_search_ctx(ctx);14181418+ if (m)14191419+ unmap_mft_record(base_ni);14201420+ ni->runlist.rl = NULL;14211421+ up_write(&ni->runlist.lock);14221422+rl_err_out:14231423+ if (rl) {14241424+ if (ntfs_cluster_free_from_rl(vol, rl) < 0) {14251425+ ntfs_error(vol->sb, "Failed to release allocated "14261426+ "cluster(s) in error code path. Run "14271427+ "chkdsk to recover the lost "14281428+ "cluster(s).");14291429+ NVolSetErrors(vol);14301430+ }14311431+ ntfs_free(rl);14321432+page_err_out:14331433+ unlock_page(page);14341434+ page_cache_release(page);14351435+ }14361436+ if (err == -EINVAL)14371437+ err = -EIO;14381438+ return err;14391439+}14401440+14411441+/**12501442 * ntfs_attr_set - fill (a part of) an attribute with a byte12511443 * @ni: ntfs inode describing the attribute to fill12521444 * @ofs: offset inside the attribute at which to start to fill···15791127 * byte offset @ofs inside the attribute with the constant byte @val.15801128 *15811129 * This function is effectively like memset() applied to an ntfs attribute.11301130+ * Note thie function actually only operates on the page cache pages belonging11311131+ * to the ntfs attribute and it marks them dirty after doing the memset().11321132+ * Thus it relies on the vm dirty page write code paths to cause the modified11331133+ * pages to be written to the mft record/disk.15821134 *15831135 * Return 0 on success and -errno on error. An error code of -ESPIPE means15841136 * that @ofs + @cnt were outside the end of the attribute and no write was···16111155 end = ofs + cnt;16121156 end_ofs = end & ~PAGE_CACHE_MASK;16131157 /* If the end is outside the inode size return -ESPIPE. */16141614- if (unlikely(end > VFS_I(ni)->i_size)) {11581158+ if (unlikely(end > i_size_read(VFS_I(ni)))) {16151159 ntfs_error(vol->sb, "Request exceeds end of attribute.");16161160 return -ESPIPE;16171161 }···17121256 ntfs_debug("Done.");17131257 return 0;17141258}12591259+12601260+#endif /* NTFS_RW */
+13-3
fs/ntfs/attrib.h
···22 * attrib.h - Defines for attribute handling in NTFS Linux kernel driver.33 * Part of the Linux-NTFS project.44 *55- * Copyright (c) 2001-2004 Anton Altaparmakov55+ * Copyright (c) 2001-2005 Anton Altaparmakov66 * Copyright (c) 2002 Richard Russon77 *88 * This program/include file is free software; you can redistribute it and/or···6060 ATTR_RECORD *base_attr;6161} ntfs_attr_search_ctx;62626363+extern int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn);6364extern int ntfs_map_runlist(ntfs_inode *ni, VCN vcn);64656565-extern runlist_element *ntfs_find_vcn(ntfs_inode *ni, const VCN vcn,6666- const BOOL need_write);6666+extern LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn,6767+ const BOOL write_locked);6868+6969+extern runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni,7070+ const VCN vcn, const BOOL write_locked);67716872int ntfs_attr_lookup(const ATTR_TYPE type, const ntfschar *name,6973 const u32 name_len, const IGNORE_CASE_BOOL ic,···8985 MFT_RECORD *mrec);9086extern void ntfs_attr_put_search_ctx(ntfs_attr_search_ctx *ctx);91878888+#ifdef NTFS_RW8989+9290extern int ntfs_attr_size_bounds_check(const ntfs_volume *vol,9391 const ATTR_TYPE type, const s64 size);9492extern int ntfs_attr_can_be_non_resident(const ntfs_volume *vol,···1009410195extern int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size);102969797+extern int ntfs_attr_make_non_resident(ntfs_inode *ni);9898+10399extern int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt,104100 const u8 val);101101+102102+#endif /* NTFS_RW */105103106104#endif /* _LINUX_NTFS_ATTRIB_H */
+28-18
fs/ntfs/compress.c
···9696/**9797 * zero_partial_compressed_page - zero out of bounds compressed page region9898 */9999-static void zero_partial_compressed_page(ntfs_inode *ni, struct page *page)9999+static void zero_partial_compressed_page(struct page *page,100100+ const s64 initialized_size)100101{101102 u8 *kp = page_address(page);102103 unsigned int kp_ofs;103104104105 ntfs_debug("Zeroing page region outside initialized size.");105105- if (((s64)page->index << PAGE_CACHE_SHIFT) >= ni->initialized_size) {106106+ if (((s64)page->index << PAGE_CACHE_SHIFT) >= initialized_size) {106107 /*107108 * FIXME: Using clear_page() will become wrong when we get108109 * PAGE_CACHE_SIZE != PAGE_SIZE but for now there is no problem.···111110 clear_page(kp);112111 return;113112 }114114- kp_ofs = ni->initialized_size & ~PAGE_CACHE_MASK;113113+ kp_ofs = initialized_size & ~PAGE_CACHE_MASK;115114 memset(kp + kp_ofs, 0, PAGE_CACHE_SIZE - kp_ofs);116115 return;117116}···119118/**120119 * handle_bounds_compressed_page - test for&handle out of bounds compressed page121120 */122122-static inline void handle_bounds_compressed_page(ntfs_inode *ni,123123- struct page *page)121121+static inline void handle_bounds_compressed_page(struct page *page,122122+ const loff_t i_size, const s64 initialized_size)124123{125125- if ((page->index >= (ni->initialized_size >> PAGE_CACHE_SHIFT)) &&126126- (ni->initialized_size < VFS_I(ni)->i_size))127127- zero_partial_compressed_page(ni, page);124124+ if ((page->index >= (initialized_size >> PAGE_CACHE_SHIFT)) &&125125+ (initialized_size < i_size))126126+ zero_partial_compressed_page(page, initialized_size);128127 return;129128}130129···139138 * @xpage_done: set to 1 if xpage was completed successfully (IN/OUT)140139 * @cb_start: compression block to decompress (IN)141140 * @cb_size: size of compression block @cb_start in bytes (IN)141141+ * @i_size: file size when we started the read (IN)142142+ * @initialized_size: initialized file size when we started the read (IN)142143 *143144 * The caller must have disabled preemption. ntfs_decompress() reenables it when144145 * the critical section is finished.···168165static int ntfs_decompress(struct page *dest_pages[], int *dest_index,169166 int *dest_ofs, const int dest_max_index, const int dest_max_ofs,170167 const int xpage, char *xpage_done, u8 *const cb_start,171171- const u32 cb_size)168168+ const u32 cb_size, const loff_t i_size,169169+ const s64 initialized_size)172170{173171 /*174172 * Pointers into the compressed data, i.e. the compression block (cb),···223219 spin_unlock(&ntfs_cb_lock);224220 /* Second stage: finalize completed pages. */225221 if (nr_completed_pages > 0) {226226- struct page *page = dest_pages[completed_pages[0]];227227- ntfs_inode *ni = NTFS_I(page->mapping->host);228228-229222 for (i = 0; i < nr_completed_pages; i++) {230223 int di = completed_pages[i];231224···231230 * If we are outside the initialized size, zero232231 * the out of bounds page range.233232 */234234- handle_bounds_compressed_page(ni, dp);233233+ handle_bounds_compressed_page(dp, i_size,234234+ initialized_size);235235 flush_dcache_page(dp);236236 kunmap(dp);237237 SetPageUptodate(dp);···480478 */481479int ntfs_read_compressed_block(struct page *page)482480{481481+ loff_t i_size;482482+ s64 initialized_size;483483 struct address_space *mapping = page->mapping;484484 ntfs_inode *ni = NTFS_I(mapping->host);485485 ntfs_volume *vol = ni->vol;486486 struct super_block *sb = vol->sb;487487 runlist_element *rl;488488- unsigned long block_size = sb->s_blocksize;488488+ unsigned long flags, block_size = sb->s_blocksize;489489 unsigned char block_size_bits = sb->s_blocksize_bits;490490 u8 *cb, *cb_pos, *cb_end;491491 struct buffer_head **bhs;···556552 * The remaining pages need to be allocated and inserted into the page557553 * cache, alignment guarantees keep all the below much simpler. (-8558554 */559559- max_page = ((VFS_I(ni)->i_size + PAGE_CACHE_SIZE - 1) >>560560- PAGE_CACHE_SHIFT) - offset;555555+ read_lock_irqsave(&ni->size_lock, flags);556556+ i_size = i_size_read(VFS_I(ni));557557+ initialized_size = ni->initialized_size;558558+ read_unlock_irqrestore(&ni->size_lock, flags);559559+ max_page = ((i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT) -560560+ offset;561561 if (nr_pages < max_page)562562 max_page = nr_pages;563563 for (i = 0; i < max_page; i++, offset++) {···832824 * If we are outside the initialized size, zero833825 * the out of bounds page range.834826 */835835- handle_bounds_compressed_page(ni, page);827827+ handle_bounds_compressed_page(page, i_size,828828+ initialized_size);836829 flush_dcache_page(page);837830 kunmap(page);838831 SetPageUptodate(page);···856847 ntfs_debug("Found compressed compression block.");857848 err = ntfs_decompress(pages, &cur_page, &cur_ofs,858849 cb_max_page, cb_max_ofs, xpage, &xpage_done,859859- cb_pos, cb_size - (cb_pos - cb));850850+ cb_pos, cb_size - (cb_pos - cb), i_size,851851+ initialized_size);860852 /*861853 * We can sleep from now on, lock already dropped by862854 * ntfs_decompress().
···11/**22 * dir.c - NTFS kernel directory operations. Part of the Linux-NTFS project.33 *44- * Copyright (c) 2001-2004 Anton Altaparmakov44+ * Copyright (c) 2001-2005 Anton Altaparmakov55 * Copyright (c) 2002 Richard Russon66 *77 * This program/include file is free software; you can redistribute it and/or···183183 name->len = 0;184184 *res = name;185185 } else {186186- if (name)187187- kfree(name);186186+ kfree(name);188187 *res = NULL;189188 }190189 mref = le64_to_cpu(ie->data.dir.indexed_file);···443444 name->len = 0;444445 *res = name;445446 } else {446446- if (name)447447- kfree(name);447447+ kfree(name);448448 *res = NULL;449449 }450450 mref = le64_to_cpu(ie->data.dir.indexed_file);···608610// TODO: (AIA)609611// The algorithm embedded in this code will be required for the time when we610612// want to support adding of entries to directories, where we require correct611611-// collation of file names in order not to cause corruption of the file system.613613+// collation of file names in order not to cause corruption of the filesystem.612614613615/**614616 * ntfs_lookup_inode_by_name - find an inode in a directory given its name···10991101static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir)11001102{11011103 s64 ia_pos, ia_start, prev_ia_pos, bmp_pos;11021102- loff_t fpos;11041104+ loff_t fpos, i_size;11031105 struct inode *bmp_vi, *vdir = filp->f_dentry->d_inode;11041106 struct super_block *sb = vdir->i_sb;11051107 ntfs_inode *ndir = NTFS_I(vdir);···11201122 vdir->i_ino, fpos);11211123 rc = err = 0;11221124 /* Are we at end of dir yet? */11231123- if (fpos >= vdir->i_size + vol->mft_record_size)11251125+ i_size = i_size_read(vdir);11261126+ if (fpos >= i_size + vol->mft_record_size)11241127 goto done;11251128 /* Emulate . and .. for all directories. */11261129 if (!fpos) {···12631264 bmp_mapping = bmp_vi->i_mapping;12641265 /* Get the starting bitmap bit position and sanity check it. */12651266 bmp_pos = ia_pos >> ndir->itype.index.block_size_bits;12661266- if (unlikely(bmp_pos >> 3 >= bmp_vi->i_size)) {12671267+ if (unlikely(bmp_pos >> 3 >= i_size_read(bmp_vi))) {12671268 ntfs_error(sb, "Current index allocation position exceeds "12681269 "index bitmap size.");12691270 goto err_out;···13001301 goto get_next_bmp_page;13011302 }13021303 /* If we have reached the end of the bitmap, we are done. */13031303- if (unlikely(((bmp_pos + cur_bmp_pos) >> 3) >= vdir->i_size))13041304+ if (unlikely(((bmp_pos + cur_bmp_pos) >> 3) >= i_size))13041305 goto unm_EOD;13051306 ia_pos = (bmp_pos + cur_bmp_pos) <<13061307 ndir->itype.index.block_size_bits;···13081309 ntfs_debug("Handling index buffer 0x%llx.",13091310 (unsigned long long)bmp_pos + cur_bmp_pos);13101311 /* If the current index buffer is in the same page we reuse the page. */13111311- if ((prev_ia_pos & PAGE_CACHE_MASK) != (ia_pos & PAGE_CACHE_MASK)) {13121312+ if ((prev_ia_pos & (s64)PAGE_CACHE_MASK) !=13131313+ (ia_pos & (s64)PAGE_CACHE_MASK)) {13121314 prev_ia_pos = ia_pos;13131315 if (likely(ia_page != NULL)) {13141316 unlock_page(ia_page);···14411441 ntfs_unmap_page(bmp_page);14421442EOD:14431443 /* We are finished, set fpos to EOD. */14441444- fpos = vdir->i_size + vol->mft_record_size;14441444+ fpos = i_size + vol->mft_record_size;14451445abort:14461446 kfree(name);14471447done:···14611461 unlock_page(ia_page);14621462 ntfs_unmap_page(ia_page);14631463 }14641464- if (ir)14651465- kfree(ir);14661466- if (name)14671467- kfree(name);14641464+ kfree(ir);14651465+ kfree(name);14681466 if (ctx)14691467 ntfs_attr_put_search_ctx(ctx);14701468 if (m)···14931495static int ntfs_dir_open(struct inode *vi, struct file *filp)14941496{14951497 if (sizeof(unsigned long) < 8) {14961496- if (vi->i_size > MAX_LFS_FILESIZE)14981498+ if (i_size_read(vi) > MAX_LFS_FILESIZE)14971499 return -EFBIG;14981500 }14991501 return 0;
+1-1
fs/ntfs/file.c
···4747static int ntfs_file_open(struct inode *vi, struct file *filp)4848{4949 if (sizeof(unsigned long) < 8) {5050- if (vi->i_size > MAX_LFS_FILESIZE)5050+ if (i_size_read(vi) > MAX_LFS_FILESIZE)5151 return -EFBIG;5252 }5353 return generic_file_open(vi, filp);
+3-13
fs/ntfs/index.c
···11/*22 * index.c - NTFS kernel index handling. Part of the Linux-NTFS project.33 *44- * Copyright (c) 2004 Anton Altaparmakov44+ * Copyright (c) 2004-2005 Anton Altaparmakov55 *66 * This program/include file is free software; you can redistribute it and/or77 * modify it under the terms of the GNU General Public License as published···3939 ntfs_index_context *ictx;40404141 ictx = kmem_cache_alloc(ntfs_index_ctx_cache, SLAB_NOFS);4242- if (ictx) {4343- ictx->idx_ni = idx_ni;4444- ictx->entry = NULL;4545- ictx->data = NULL;4646- ictx->data_len = 0;4747- ictx->is_in_root = 0;4848- ictx->ir = NULL;4949- ictx->actx = NULL;5050- ictx->base_ni = NULL;5151- ictx->ia = NULL;5252- ictx->page = NULL;5353- }4242+ if (ictx)4343+ *ictx = (ntfs_index_context){ .idx_ni = idx_ni };5444 return ictx;5545}5646
+262-268
fs/ntfs/inode.c
···11/**22 * inode.c - NTFS kernel inode handling. Part of the Linux-NTFS project.33 *44- * Copyright (c) 2001-2004 Anton Altaparmakov44+ * Copyright (c) 2001-2005 Anton Altaparmakov55 *66 * This program/include file is free software; you can redistribute it and/or77 * modify it under the terms of the GNU General Public License as published···174174175175 vi = iget5_locked(sb, mft_no, (test_t)ntfs_test_inode,176176 (set_t)ntfs_init_locked_inode, &na);177177- if (!vi)177177+ if (unlikely(!vi))178178 return ERR_PTR(-ENOMEM);179179180180 err = 0;···188188 * There is no point in keeping bad inodes around if the failure was189189 * due to ENOMEM. We want to be able to retry again later.190190 */191191- if (err == -ENOMEM) {191191+ if (unlikely(err == -ENOMEM)) {192192 iput(vi);193193 vi = ERR_PTR(err);194194 }···235235236236 vi = iget5_locked(base_vi->i_sb, na.mft_no, (test_t)ntfs_test_inode,237237 (set_t)ntfs_init_locked_inode, &na);238238- if (!vi)238238+ if (unlikely(!vi))239239 return ERR_PTR(-ENOMEM);240240241241 err = 0;···250250 * simplifies things in that we never need to check for bad attribute251251 * inodes elsewhere.252252 */253253- if (err) {253253+ if (unlikely(err)) {254254 iput(vi);255255 vi = ERR_PTR(err);256256 }···290290291291 vi = iget5_locked(base_vi->i_sb, na.mft_no, (test_t)ntfs_test_inode,292292 (set_t)ntfs_init_locked_inode, &na);293293- if (!vi)293293+ if (unlikely(!vi))294294 return ERR_PTR(-ENOMEM);295295296296 err = 0;···305305 * simplifies things in that we never need to check for bad index306306 * inodes elsewhere.307307 */308308- if (err) {308308+ if (unlikely(err)) {309309 iput(vi);310310 vi = ERR_PTR(err);311311 }···317317 ntfs_inode *ni;318318319319 ntfs_debug("Entering.");320320- ni = (ntfs_inode *)kmem_cache_alloc(ntfs_big_inode_cache,321321- SLAB_NOFS);320320+ ni = kmem_cache_alloc(ntfs_big_inode_cache, SLAB_NOFS);322321 if (likely(ni != NULL)) {323322 ni->state = 0;324323 return VFS_I(ni);···342343 ntfs_inode *ni;343344344345 ntfs_debug("Entering.");345345- ni = (ntfs_inode *)kmem_cache_alloc(ntfs_inode_cache, SLAB_NOFS);346346+ ni = kmem_cache_alloc(ntfs_inode_cache, SLAB_NOFS);346347 if (likely(ni != NULL)) {347348 ni->state = 0;348349 return ni;···375376void __ntfs_init_inode(struct super_block *sb, ntfs_inode *ni)376377{377378 ntfs_debug("Entering.");379379+ rwlock_init(&ni->size_lock);378380 ni->initialized_size = ni->allocated_size = 0;379381 ni->seq_no = 0;380382 atomic_set(&ni->count, 1);···524524 ntfs_volume *vol = NTFS_SB(vi->i_sb);525525 ntfs_inode *ni;526526 MFT_RECORD *m;527527+ ATTR_RECORD *a;527528 STANDARD_INFORMATION *si;528529 ntfs_attr_search_ctx *ctx;529530 int err = 0;···633632 }634633 goto unm_err_out;635634 }635635+ a = ctx->attr;636636 /* Get the standard information attribute value. */637637- si = (STANDARD_INFORMATION*)((char*)ctx->attr +638638- le16_to_cpu(ctx->attr->data.resident.value_offset));637637+ si = (STANDARD_INFORMATION*)((u8*)a +638638+ le16_to_cpu(a->data.resident.value_offset));639639640640 /* Transfer information from the standard information into vi. */641641 /*···675673 goto skip_attr_list_load;676674 ntfs_debug("Attribute list found in inode 0x%lx.", vi->i_ino);677675 NInoSetAttrList(ni);678678- if (ctx->attr->flags & ATTR_IS_ENCRYPTED ||679679- ctx->attr->flags & ATTR_COMPRESSION_MASK ||680680- ctx->attr->flags & ATTR_IS_SPARSE) {676676+ a = ctx->attr;677677+ if (a->flags & ATTR_IS_ENCRYPTED ||678678+ a->flags & ATTR_COMPRESSION_MASK ||679679+ a->flags & ATTR_IS_SPARSE) {681680 ntfs_error(vi->i_sb, "Attribute list attribute is "682681 "compressed/encrypted/sparse.");683682 goto unm_err_out;684683 }685684 /* Now allocate memory for the attribute list. */686686- ni->attr_list_size = (u32)ntfs_attr_size(ctx->attr);685685+ ni->attr_list_size = (u32)ntfs_attr_size(a);687686 ni->attr_list = ntfs_malloc_nofs(ni->attr_list_size);688687 if (!ni->attr_list) {689688 ntfs_error(vi->i_sb, "Not enough memory to allocate "···692689 err = -ENOMEM;693690 goto unm_err_out;694691 }695695- if (ctx->attr->non_resident) {692692+ if (a->non_resident) {696693 NInoSetAttrListNonResident(ni);697697- if (ctx->attr->data.non_resident.lowest_vcn) {694694+ if (a->data.non_resident.lowest_vcn) {698695 ntfs_error(vi->i_sb, "Attribute list has non "699696 "zero lowest_vcn.");700697 goto unm_err_out;···704701 * exclusive access to the inode at this time.705702 */706703 ni->attr_list_rl.rl = ntfs_mapping_pairs_decompress(vol,707707- ctx->attr, NULL);704704+ a, NULL);708705 if (IS_ERR(ni->attr_list_rl.rl)) {709706 err = PTR_ERR(ni->attr_list_rl.rl);710707 ni->attr_list_rl.rl = NULL;···715712 /* Now load the attribute list. */716713 if ((err = load_attribute_list(vol, &ni->attr_list_rl,717714 ni->attr_list, ni->attr_list_size,718718- sle64_to_cpu(ctx->attr->data.719719- non_resident.initialized_size)))) {715715+ sle64_to_cpu(a->data.non_resident.716716+ initialized_size)))) {720717 ntfs_error(vi->i_sb, "Failed to load "721718 "attribute list attribute.");722719 goto unm_err_out;723720 }724724- } else /* if (!ctx.attr->non_resident) */ {725725- if ((u8*)ctx->attr + le16_to_cpu(726726- ctx->attr->data.resident.value_offset) +727727- le32_to_cpu(728728- ctx->attr->data.resident.value_length) >721721+ } else /* if (!a->non_resident) */ {722722+ if ((u8*)a + le16_to_cpu(a->data.resident.value_offset)723723+ + le32_to_cpu(724724+ a->data.resident.value_length) >729725 (u8*)ctx->mrec + vol->mft_record_size) {730726 ntfs_error(vi->i_sb, "Corrupt attribute list "731727 "in inode.");732728 goto unm_err_out;733729 }734730 /* Now copy the attribute list. */735735- memcpy(ni->attr_list, (u8*)ctx->attr + le16_to_cpu(736736- ctx->attr->data.resident.value_offset),731731+ memcpy(ni->attr_list, (u8*)a + le16_to_cpu(732732+ a->data.resident.value_offset),737733 le32_to_cpu(738738- ctx->attr->data.resident.value_length));734734+ a->data.resident.value_length));739735 }740736 }741737skip_attr_list_load:···743741 * in ntfs_ino->attr_list and it is ntfs_ino->attr_list_size bytes.744742 */745743 if (S_ISDIR(vi->i_mode)) {744744+ loff_t bvi_size;746745 struct inode *bvi;747746 ntfs_inode *bni;748747 INDEX_ROOT *ir;749749- char *ir_end, *index_end;748748+ u8 *ir_end, *index_end;750749751750 /* It is a directory, find index root attribute. */752751 ntfs_attr_reinit_search_ctx(ctx);···763760 }764761 goto unm_err_out;765762 }763763+ a = ctx->attr;766764 /* Set up the state. */767767- if (unlikely(ctx->attr->non_resident)) {765765+ if (unlikely(a->non_resident)) {768766 ntfs_error(vol->sb, "$INDEX_ROOT attribute is not "769767 "resident.");770768 goto unm_err_out;771769 }772770 /* Ensure the attribute name is placed before the value. */773773- if (unlikely(ctx->attr->name_length &&774774- (le16_to_cpu(ctx->attr->name_offset) >=775775- le16_to_cpu(ctx->attr->data.resident.776776- value_offset)))) {771771+ if (unlikely(a->name_length && (le16_to_cpu(a->name_offset) >=772772+ le16_to_cpu(a->data.resident.value_offset)))) {777773 ntfs_error(vol->sb, "$INDEX_ROOT attribute name is "778774 "placed after the attribute value.");779775 goto unm_err_out;···783781 * encrypted. However index root cannot be both compressed and784782 * encrypted.785783 */786786- if (ctx->attr->flags & ATTR_COMPRESSION_MASK)784784+ if (a->flags & ATTR_COMPRESSION_MASK)787785 NInoSetCompressed(ni);788788- if (ctx->attr->flags & ATTR_IS_ENCRYPTED) {789789- if (ctx->attr->flags & ATTR_COMPRESSION_MASK) {786786+ if (a->flags & ATTR_IS_ENCRYPTED) {787787+ if (a->flags & ATTR_COMPRESSION_MASK) {790788 ntfs_error(vi->i_sb, "Found encrypted and "791789 "compressed attribute.");792790 goto unm_err_out;793791 }794792 NInoSetEncrypted(ni);795793 }796796- if (ctx->attr->flags & ATTR_IS_SPARSE)794794+ if (a->flags & ATTR_IS_SPARSE)797795 NInoSetSparse(ni);798798- ir = (INDEX_ROOT*)((char*)ctx->attr + le16_to_cpu(799799- ctx->attr->data.resident.value_offset));800800- ir_end = (char*)ir + le32_to_cpu(801801- ctx->attr->data.resident.value_length);802802- if (ir_end > (char*)ctx->mrec + vol->mft_record_size) {796796+ ir = (INDEX_ROOT*)((u8*)a +797797+ le16_to_cpu(a->data.resident.value_offset));798798+ ir_end = (u8*)ir + le32_to_cpu(a->data.resident.value_length);799799+ if (ir_end > (u8*)ctx->mrec + vol->mft_record_size) {803800 ntfs_error(vi->i_sb, "$INDEX_ROOT attribute is "804801 "corrupt.");805802 goto unm_err_out;806803 }807807- index_end = (char*)&ir->index +804804+ index_end = (u8*)&ir->index +808805 le32_to_cpu(ir->index.index_length);809806 if (index_end > ir_end) {810807 ntfs_error(vi->i_sb, "Directory index is corrupt.");···890889 "attribute.");891890 goto unm_err_out;892891 }893893- if (!ctx->attr->non_resident) {892892+ a = ctx->attr;893893+ if (!a->non_resident) {894894 ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute "895895 "is resident.");896896 goto unm_err_out;···900898 * Ensure the attribute name is placed before the mapping pairs901899 * array.902900 */903903- if (unlikely(ctx->attr->name_length &&904904- (le16_to_cpu(ctx->attr->name_offset) >=905905- le16_to_cpu(ctx->attr->data.non_resident.906906- mapping_pairs_offset)))) {901901+ if (unlikely(a->name_length && (le16_to_cpu(a->name_offset) >=902902+ le16_to_cpu(903903+ a->data.non_resident.mapping_pairs_offset)))) {907904 ntfs_error(vol->sb, "$INDEX_ALLOCATION attribute name "908905 "is placed after the mapping pairs "909906 "array.");910907 goto unm_err_out;911908 }912912- if (ctx->attr->flags & ATTR_IS_ENCRYPTED) {909909+ if (a->flags & ATTR_IS_ENCRYPTED) {913910 ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute "914911 "is encrypted.");915912 goto unm_err_out;916913 }917917- if (ctx->attr->flags & ATTR_IS_SPARSE) {914914+ if (a->flags & ATTR_IS_SPARSE) {918915 ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute "919916 "is sparse.");920917 goto unm_err_out;921918 }922922- if (ctx->attr->flags & ATTR_COMPRESSION_MASK) {919919+ if (a->flags & ATTR_COMPRESSION_MASK) {923920 ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute "924921 "is compressed.");925922 goto unm_err_out;926923 }927927- if (ctx->attr->data.non_resident.lowest_vcn) {924924+ if (a->data.non_resident.lowest_vcn) {928925 ntfs_error(vi->i_sb, "First extent of "929926 "$INDEX_ALLOCATION attribute has non "930927 "zero lowest_vcn.");931928 goto unm_err_out;932929 }933933- vi->i_size = sle64_to_cpu(934934- ctx->attr->data.non_resident.data_size);930930+ vi->i_size = sle64_to_cpu(a->data.non_resident.data_size);935931 ni->initialized_size = sle64_to_cpu(936936- ctx->attr->data.non_resident.initialized_size);932932+ a->data.non_resident.initialized_size);937933 ni->allocated_size = sle64_to_cpu(938938- ctx->attr->data.non_resident.allocated_size);934934+ a->data.non_resident.allocated_size);939935 /*940936 * We are done with the mft record, so we release it. Otherwise941937 * we would deadlock in ntfs_attr_iget().···958958 goto unm_err_out;959959 }960960 /* Consistency check bitmap size vs. index allocation size. */961961- if ((bvi->i_size << 3) < (vi->i_size >>961961+ bvi_size = i_size_read(bvi);962962+ if ((bvi_size << 3) < (vi->i_size >>962963 ni->itype.index.block_size_bits)) {963964 ntfs_error(vi->i_sb, "Index bitmap too small (0x%llx) "964965 "for index allocation (0x%llx).",965965- bvi->i_size << 3, vi->i_size);966966+ bvi_size << 3, vi->i_size);966967 goto unm_err_out;967968 }968969skip_large_dir_stuff:···10111010 ntfs_error(vi->i_sb, "$DATA attribute is missing.");10121011 goto unm_err_out;10131012 }10131013+ a = ctx->attr;10141014 /* Setup the state. */10151015- if (ctx->attr->non_resident) {10151015+ if (a->non_resident) {10161016 NInoSetNonResident(ni);10171017- if (ctx->attr->flags & ATTR_COMPRESSION_MASK) {10181018- NInoSetCompressed(ni);10191019- if (vol->cluster_size > 4096) {10201020- ntfs_error(vi->i_sb, "Found "10211021- "compressed data but "10221022- "compression is disabled due "10231023- "to cluster size (%i) > 4kiB.",10241024- vol->cluster_size);10251025- goto unm_err_out;10171017+ if (a->flags & (ATTR_COMPRESSION_MASK |10181018+ ATTR_IS_SPARSE)) {10191019+ if (a->flags & ATTR_COMPRESSION_MASK) {10201020+ NInoSetCompressed(ni);10211021+ if (vol->cluster_size > 4096) {10221022+ ntfs_error(vi->i_sb, "Found "10231023+ "compressed data but "10241024+ "compression is "10251025+ "disabled due to "10261026+ "cluster size (%i) > "10271027+ "4kiB.",10281028+ vol->cluster_size);10291029+ goto unm_err_out;10301030+ }10311031+ if ((a->flags & ATTR_COMPRESSION_MASK)10321032+ != ATTR_IS_COMPRESSED) {10331033+ ntfs_error(vi->i_sb, "Found "10341034+ "unknown compression "10351035+ "method or corrupt "10361036+ "file.");10371037+ goto unm_err_out;10381038+ }10261039 }10271027- if ((ctx->attr->flags & ATTR_COMPRESSION_MASK)10281028- != ATTR_IS_COMPRESSED) {10291029- ntfs_error(vi->i_sb, "Found "10301030- "unknown compression method or "10311031- "corrupt file.");10321032- goto unm_err_out;10331033- }10341034- ni->itype.compressed.block_clusters = 1U <<10351035- ctx->attr->data.non_resident.10361036- compression_unit;10371037- if (ctx->attr->data.non_resident.10381038- compression_unit != 4) {10401040+ if (a->flags & ATTR_IS_SPARSE)10411041+ NInoSetSparse(ni);10421042+ if (a->data.non_resident.compression_unit !=10431043+ 4) {10391044 ntfs_error(vi->i_sb, "Found "10401045 "nonstandard compression unit "10411046 "(%u instead of 4). Cannot "10421047 "handle this.",10431043- ctx->attr->data.non_resident.10481048+ a->data.non_resident.10441049 compression_unit);10451050 err = -EOPNOTSUPP;10461051 goto unm_err_out;10471052 }10531053+ ni->itype.compressed.block_clusters = 1U <<10541054+ a->data.non_resident.10551055+ compression_unit;10481056 ni->itype.compressed.block_size = 1U << (10491049- ctx->attr->data.non_resident.10571057+ a->data.non_resident.10501058 compression_unit +10511059 vol->cluster_size_bits);10521060 ni->itype.compressed.block_size_bits = ffs(10531053- ni->itype.compressed.block_size) - 1;10611061+ ni->itype.compressed.10621062+ block_size) - 1;10631063+ ni->itype.compressed.size = sle64_to_cpu(10641064+ a->data.non_resident.10651065+ compressed_size);10541066 }10551055- if (ctx->attr->flags & ATTR_IS_ENCRYPTED) {10561056- if (ctx->attr->flags & ATTR_COMPRESSION_MASK) {10671067+ if (a->flags & ATTR_IS_ENCRYPTED) {10681068+ if (a->flags & ATTR_COMPRESSION_MASK) {10571069 ntfs_error(vi->i_sb, "Found encrypted "10581070 "and compressed data.");10591071 goto unm_err_out;10601072 }10611073 NInoSetEncrypted(ni);10621074 }10631063- if (ctx->attr->flags & ATTR_IS_SPARSE)10641064- NInoSetSparse(ni);10651065- if (ctx->attr->data.non_resident.lowest_vcn) {10751075+ if (a->data.non_resident.lowest_vcn) {10661076 ntfs_error(vi->i_sb, "First extent of $DATA "10671077 "attribute has non zero "10681078 "lowest_vcn.");10691079 goto unm_err_out;10701080 }10711071- /* Setup all the sizes. */10721081 vi->i_size = sle64_to_cpu(10731073- ctx->attr->data.non_resident.data_size);10821082+ a->data.non_resident.data_size);10741083 ni->initialized_size = sle64_to_cpu(10751075- ctx->attr->data.non_resident.10761076- initialized_size);10841084+ a->data.non_resident.initialized_size);10771085 ni->allocated_size = sle64_to_cpu(10781078- ctx->attr->data.non_resident.10791079- allocated_size);10801080- if (NInoCompressed(ni)) {10811081- ni->itype.compressed.size = sle64_to_cpu(10821082- ctx->attr->data.non_resident.10831083- compressed_size);10841084- }10861086+ a->data.non_resident.allocated_size);10851087 } else { /* Resident attribute. */10861086- /*10871087- * Make all sizes equal for simplicity in read code10881088- * paths. FIXME: Need to keep this in mind when10891089- * converting to non-resident attribute in write code10901090- * path. (Probably only affects truncate().)10911091- */10921092- vi->i_size = ni->initialized_size = ni->allocated_size =10931093- le32_to_cpu(10941094- ctx->attr->data.resident.value_length);10881088+ vi->i_size = ni->initialized_size = le32_to_cpu(10891089+ a->data.resident.value_length);10901090+ ni->allocated_size = le32_to_cpu(a->length) -10911091+ le16_to_cpu(10921092+ a->data.resident.value_offset);10931093+ if (vi->i_size > ni->allocated_size) {10941094+ ntfs_error(vi->i_sb, "Resident data attribute "10951095+ "is corrupt (size exceeds "10961096+ "allocation).");10971097+ goto unm_err_out;10981098+ }10951099 }10961100no_data_attr_special_case:10971101 /* We are done with the mft record, so we release it. */···11231117 * sizes of all non-resident attributes present to give us the Linux11241118 * correct size that should go into i_blocks (after division by 512).11251119 */11261126- if (S_ISDIR(vi->i_mode) || !NInoCompressed(ni))11271127- vi->i_blocks = ni->allocated_size >> 9;11281128- else11201120+ if (S_ISREG(vi->i_mode) && (NInoCompressed(ni) || NInoSparse(ni)))11291121 vi->i_blocks = ni->itype.compressed.size >> 9;11301130-11221122+ else11231123+ vi->i_blocks = ni->allocated_size >> 9;11311124 ntfs_debug("Done.");11321125 return 0;11331126···11711166 ntfs_volume *vol = NTFS_SB(vi->i_sb);11721167 ntfs_inode *ni, *base_ni;11731168 MFT_RECORD *m;11691169+ ATTR_RECORD *a;11741170 ntfs_attr_search_ctx *ctx;11751171 int err = 0;11761172···12061200 err = -ENOMEM;12071201 goto unm_err_out;12081202 }12091209-12101203 /* Find the attribute. */12111204 err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,12121205 CASE_SENSITIVE, 0, NULL, 0, ctx);12131206 if (unlikely(err))12141207 goto unm_err_out;12151215-12161216- if (!ctx->attr->non_resident) {12081208+ a = ctx->attr;12091209+ if (!a->non_resident) {12171210 /* Ensure the attribute name is placed before the value. */12181218- if (unlikely(ctx->attr->name_length &&12191219- (le16_to_cpu(ctx->attr->name_offset) >=12201220- le16_to_cpu(ctx->attr->data.resident.12211221- value_offset)))) {12111211+ if (unlikely(a->name_length && (le16_to_cpu(a->name_offset) >=12121212+ le16_to_cpu(a->data.resident.value_offset)))) {12221213 ntfs_error(vol->sb, "Attribute name is placed after "12231214 "the attribute value.");12241215 goto unm_err_out;12251216 }12261226- if (NInoMstProtected(ni) || ctx->attr->flags) {12171217+ if (NInoMstProtected(ni) || a->flags) {12271218 ntfs_error(vi->i_sb, "Found mst protected attribute "12281219 "or attribute with non-zero flags but "12291220 "the attribute is resident. Please "···12281225 "linux-ntfs-dev@lists.sourceforge.net");12291226 goto unm_err_out;12301227 }12311231- /*12321232- * Resident attribute. Make all sizes equal for simplicity in12331233- * read code paths.12341234- */12351235- vi->i_size = ni->initialized_size = ni->allocated_size =12361236- le32_to_cpu(ctx->attr->data.resident.value_length);12281228+ vi->i_size = ni->initialized_size = le32_to_cpu(12291229+ a->data.resident.value_length);12301230+ ni->allocated_size = le32_to_cpu(a->length) -12311231+ le16_to_cpu(a->data.resident.value_offset);12321232+ if (vi->i_size > ni->allocated_size) {12331233+ ntfs_error(vi->i_sb, "Resident attribute is corrupt "12341234+ "(size exceeds allocation).");12351235+ goto unm_err_out;12361236+ }12371237 } else {12381238 NInoSetNonResident(ni);12391239 /*12401240 * Ensure the attribute name is placed before the mapping pairs12411241 * array.12421242 */12431243- if (unlikely(ctx->attr->name_length &&12441244- (le16_to_cpu(ctx->attr->name_offset) >=12451245- le16_to_cpu(ctx->attr->data.non_resident.12461246- mapping_pairs_offset)))) {12431243+ if (unlikely(a->name_length && (le16_to_cpu(a->name_offset) >=12441244+ le16_to_cpu(12451245+ a->data.non_resident.mapping_pairs_offset)))) {12471246 ntfs_error(vol->sb, "Attribute name is placed after "12481247 "the mapping pairs array.");12491248 goto unm_err_out;12501249 }12511251- if (ctx->attr->flags & ATTR_COMPRESSION_MASK) {12501250+ if (a->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_SPARSE)) {12511251+ if (a->flags & ATTR_COMPRESSION_MASK) {12521252+ NInoSetCompressed(ni);12531253+ if ((ni->type != AT_DATA) || (ni->type ==12541254+ AT_DATA && ni->name_len)) {12551255+ ntfs_error(vi->i_sb, "Found compressed "12561256+ "non-data or named "12571257+ "data attribute. "12581258+ "Please report you "12591259+ "saw this message to "12601260+ "linux-ntfs-dev@lists."12611261+ "sourceforge.net");12621262+ goto unm_err_out;12631263+ }12641264+ if (vol->cluster_size > 4096) {12651265+ ntfs_error(vi->i_sb, "Found compressed "12661266+ "attribute but "12671267+ "compression is "12681268+ "disabled due to "12691269+ "cluster size (%i) > "12701270+ "4kiB.",12711271+ vol->cluster_size);12721272+ goto unm_err_out;12731273+ }12741274+ if ((a->flags & ATTR_COMPRESSION_MASK) !=12751275+ ATTR_IS_COMPRESSED) {12761276+ ntfs_error(vi->i_sb, "Found unknown "12771277+ "compression method.");12781278+ goto unm_err_out;12791279+ }12801280+ }12521281 if (NInoMstProtected(ni)) {12531282 ntfs_error(vi->i_sb, "Found mst protected "12541283 "attribute but the attribute "12551255- "is compressed. Please report "12561256- "you saw this message to "12841284+ "is %s. Please report you "12851285+ "saw this message to "12571286 "linux-ntfs-dev@lists."12581258- "sourceforge.net");12871287+ "sourceforge.net",12881288+ NInoCompressed(ni) ?12891289+ "compressed" : "sparse");12591290 goto unm_err_out;12601291 }12611261- NInoSetCompressed(ni);12621262- if ((ni->type != AT_DATA) || (ni->type == AT_DATA &&12631263- ni->name_len)) {12641264- ntfs_error(vi->i_sb, "Found compressed "12651265- "non-data or named data "12661266- "attribute. Please report "12671267- "you saw this message to "12681268- "linux-ntfs-dev@lists."12691269- "sourceforge.net");12701270- goto unm_err_out;12711271- }12721272- if (vol->cluster_size > 4096) {12731273- ntfs_error(vi->i_sb, "Found compressed "12741274- "attribute but compression is "12751275- "disabled due to cluster size "12761276- "(%i) > 4kiB.",12771277- vol->cluster_size);12781278- goto unm_err_out;12791279- }12801280- if ((ctx->attr->flags & ATTR_COMPRESSION_MASK)12811281- != ATTR_IS_COMPRESSED) {12821282- ntfs_error(vi->i_sb, "Found unknown "12831283- "compression method.");12841284- goto unm_err_out;12851285- }12861286- ni->itype.compressed.block_clusters = 1U <<12871287- ctx->attr->data.non_resident.12881288- compression_unit;12891289- if (ctx->attr->data.non_resident.compression_unit !=12901290- 4) {12921292+ if (a->flags & ATTR_IS_SPARSE)12931293+ NInoSetSparse(ni);12941294+ if (a->data.non_resident.compression_unit != 4) {12911295 ntfs_error(vi->i_sb, "Found nonstandard "12921296 "compression unit (%u instead "12931297 "of 4). Cannot handle this.",12941294- ctx->attr->data.non_resident.12981298+ a->data.non_resident.12951299 compression_unit);12961300 err = -EOPNOTSUPP;12971301 goto unm_err_out;12981302 }13031303+ ni->itype.compressed.block_clusters = 1U <<13041304+ a->data.non_resident.compression_unit;12991305 ni->itype.compressed.block_size = 1U << (13001300- ctx->attr->data.non_resident.13011301- compression_unit +13061306+ a->data.non_resident.compression_unit +13021307 vol->cluster_size_bits);13031308 ni->itype.compressed.block_size_bits = ffs(13041304- ni->itype.compressed.block_size) - 1;13091309+ ni->itype.compressed.block_size) - 1;13101310+ ni->itype.compressed.size = sle64_to_cpu(13111311+ a->data.non_resident.compressed_size);13051312 }13061306- if (ctx->attr->flags & ATTR_IS_ENCRYPTED) {13071307- if (ctx->attr->flags & ATTR_COMPRESSION_MASK) {13081308- ntfs_error(vi->i_sb, "Found encrypted "13091309- "and compressed data.");13131313+ if (a->flags & ATTR_IS_ENCRYPTED) {13141314+ if (a->flags & ATTR_COMPRESSION_MASK) {13151315+ ntfs_error(vi->i_sb, "Found encrypted and "13161316+ "compressed data.");13101317 goto unm_err_out;13111318 }13121319 if (NInoMstProtected(ni)) {···13301317 }13311318 NInoSetEncrypted(ni);13321319 }13331333- if (ctx->attr->flags & ATTR_IS_SPARSE) {13341334- if (NInoMstProtected(ni)) {13351335- ntfs_error(vi->i_sb, "Found mst protected "13361336- "attribute but the attribute "13371337- "is sparse. Please report "13381338- "you saw this message to "13391339- "linux-ntfs-dev@lists."13401340- "sourceforge.net");13411341- goto unm_err_out;13421342- }13431343- NInoSetSparse(ni);13441344- }13451345- if (ctx->attr->data.non_resident.lowest_vcn) {13201320+ if (a->data.non_resident.lowest_vcn) {13461321 ntfs_error(vi->i_sb, "First extent of attribute has "13471322 "non-zero lowest_vcn.");13481323 goto unm_err_out;13491324 }13501350- /* Setup all the sizes. */13511351- vi->i_size = sle64_to_cpu(13521352- ctx->attr->data.non_resident.data_size);13251325+ vi->i_size = sle64_to_cpu(a->data.non_resident.data_size);13531326 ni->initialized_size = sle64_to_cpu(13541354- ctx->attr->data.non_resident.initialized_size);13271327+ a->data.non_resident.initialized_size);13551328 ni->allocated_size = sle64_to_cpu(13561356- ctx->attr->data.non_resident.allocated_size);13571357- if (NInoCompressed(ni)) {13581358- ni->itype.compressed.size = sle64_to_cpu(13591359- ctx->attr->data.non_resident.13601360- compressed_size);13611361- }13291329+ a->data.non_resident.allocated_size);13621330 }13631363-13641331 /* Setup the operations for this attribute inode. */13651332 vi->i_op = NULL;13661333 vi->i_fop = NULL;···13481355 vi->i_mapping->a_ops = &ntfs_mst_aops;13491356 else13501357 vi->i_mapping->a_ops = &ntfs_aops;13511351-13521352- if (!NInoCompressed(ni))13531353- vi->i_blocks = ni->allocated_size >> 9;13541354- else13581358+ if (NInoCompressed(ni) || NInoSparse(ni))13551359 vi->i_blocks = ni->itype.compressed.size >> 9;13561356-13601360+ else13611361+ vi->i_blocks = ni->allocated_size >> 9;13571362 /*13581363 * Make sure the base inode doesn't go away and attach it to the13591364 * attribute inode.···14201429 */14211430static int ntfs_read_locked_index_inode(struct inode *base_vi, struct inode *vi)14221431{14321432+ loff_t bvi_size;14231433 ntfs_volume *vol = NTFS_SB(vi->i_sb);14241434 ntfs_inode *ni, *base_ni, *bni;14251435 struct inode *bvi;14261436 MFT_RECORD *m;14371437+ ATTR_RECORD *a;14271438 ntfs_attr_search_ctx *ctx;14281439 INDEX_ROOT *ir;14291440 u8 *ir_end, *index_end;···14671474 "missing.");14681475 goto unm_err_out;14691476 }14771477+ a = ctx->attr;14701478 /* Set up the state. */14711471- if (unlikely(ctx->attr->non_resident)) {14791479+ if (unlikely(a->non_resident)) {14721480 ntfs_error(vol->sb, "$INDEX_ROOT attribute is not resident.");14731481 goto unm_err_out;14741482 }14751483 /* Ensure the attribute name is placed before the value. */14761476- if (unlikely(ctx->attr->name_length &&14771477- (le16_to_cpu(ctx->attr->name_offset) >=14781478- le16_to_cpu(ctx->attr->data.resident.14791479- value_offset)))) {14841484+ if (unlikely(a->name_length && (le16_to_cpu(a->name_offset) >=14851485+ le16_to_cpu(a->data.resident.value_offset)))) {14801486 ntfs_error(vol->sb, "$INDEX_ROOT attribute name is placed "14811487 "after the attribute value.");14821488 goto unm_err_out;14831489 }14841490 /* Compressed/encrypted/sparse index root is not allowed. */14851485- if (ctx->attr->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_ENCRYPTED |14911491+ if (a->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_ENCRYPTED |14861492 ATTR_IS_SPARSE)) {14871493 ntfs_error(vi->i_sb, "Found compressed/encrypted/sparse index "14881494 "root attribute.");14891495 goto unm_err_out;14901496 }14911491- ir = (INDEX_ROOT*)((u8*)ctx->attr +14921492- le16_to_cpu(ctx->attr->data.resident.value_offset));14931493- ir_end = (u8*)ir + le32_to_cpu(ctx->attr->data.resident.value_length);14971497+ ir = (INDEX_ROOT*)((u8*)a + le16_to_cpu(a->data.resident.value_offset));14981498+ ir_end = (u8*)ir + le32_to_cpu(a->data.resident.value_length);14941499 if (ir_end > (u8*)ctx->mrec + vol->mft_record_size) {14951500 ntfs_error(vi->i_sb, "$INDEX_ROOT attribute is corrupt.");14961501 goto unm_err_out;···15611570 "$INDEX_ALLOCATION attribute.");15621571 goto unm_err_out;15631572 }15641564- if (!ctx->attr->non_resident) {15731573+ if (!a->non_resident) {15651574 ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute is "15661575 "resident.");15671576 goto unm_err_out;···15691578 /*15701579 * Ensure the attribute name is placed before the mapping pairs array.15711580 */15721572- if (unlikely(ctx->attr->name_length && (le16_to_cpu(15731573- ctx->attr->name_offset) >= le16_to_cpu(15741574- ctx->attr->data.non_resident.mapping_pairs_offset)))) {15811581+ if (unlikely(a->name_length && (le16_to_cpu(a->name_offset) >=15821582+ le16_to_cpu(15831583+ a->data.non_resident.mapping_pairs_offset)))) {15751584 ntfs_error(vol->sb, "$INDEX_ALLOCATION attribute name is "15761585 "placed after the mapping pairs array.");15771586 goto unm_err_out;15781587 }15791579- if (ctx->attr->flags & ATTR_IS_ENCRYPTED) {15881588+ if (a->flags & ATTR_IS_ENCRYPTED) {15801589 ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute is "15811590 "encrypted.");15821591 goto unm_err_out;15831592 }15841584- if (ctx->attr->flags & ATTR_IS_SPARSE) {15931593+ if (a->flags & ATTR_IS_SPARSE) {15851594 ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute is sparse.");15861595 goto unm_err_out;15871596 }15881588- if (ctx->attr->flags & ATTR_COMPRESSION_MASK) {15971597+ if (a->flags & ATTR_COMPRESSION_MASK) {15891598 ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute is "15901599 "compressed.");15911600 goto unm_err_out;15921601 }15931593- if (ctx->attr->data.non_resident.lowest_vcn) {16021602+ if (a->data.non_resident.lowest_vcn) {15941603 ntfs_error(vi->i_sb, "First extent of $INDEX_ALLOCATION "15951604 "attribute has non zero lowest_vcn.");15961605 goto unm_err_out;15971606 }15981598- vi->i_size = sle64_to_cpu(ctx->attr->data.non_resident.data_size);16071607+ vi->i_size = sle64_to_cpu(a->data.non_resident.data_size);15991608 ni->initialized_size = sle64_to_cpu(16001600- ctx->attr->data.non_resident.initialized_size);16011601- ni->allocated_size = sle64_to_cpu(16021602- ctx->attr->data.non_resident.allocated_size);16091609+ a->data.non_resident.initialized_size);16101610+ ni->allocated_size = sle64_to_cpu(a->data.non_resident.allocated_size);16031611 /*16041612 * We are done with the mft record, so we release it. Otherwise16051613 * we would deadlock in ntfs_attr_iget().···16221632 goto iput_unm_err_out;16231633 }16241634 /* Consistency check bitmap size vs. index allocation size. */16251625- if ((bvi->i_size << 3) < (vi->i_size >>16261626- ni->itype.index.block_size_bits)) {16351635+ bvi_size = i_size_read(bvi);16361636+ if ((bvi_size << 3) < (vi->i_size >> ni->itype.index.block_size_bits)) {16271637 ntfs_error(vi->i_sb, "Index bitmap too small (0x%llx) for "16281628- "index allocation (0x%llx).", bvi->i_size << 3,16381638+ "index allocation (0x%llx).", bvi_size << 3,16291639 vi->i_size);16301640 goto iput_unm_err_out;16311641 }···16361646 vi->i_fop = NULL;16371647 vi->i_mapping->a_ops = &ntfs_mst_aops;16381648 vi->i_blocks = ni->allocated_size >> 9;16391639-16401649 /*16411650 * Make sure the base inode doesn't go away and attach it to the16421651 * index inode.···17011712 struct buffer_head *bh;17021713 ntfs_inode *ni;17031714 MFT_RECORD *m = NULL;17041704- ATTR_RECORD *attr;17151715+ ATTR_RECORD *a;17051716 ntfs_attr_search_ctx *ctx;17061717 unsigned int i, nr_blocks;17071718 int err;···17161727 /* Setup the data attribute. It is special as it is mst protected. */17171728 NInoSetNonResident(ni);17181729 NInoSetMstProtected(ni);17301730+ NInoSetSparseDisabled(ni);17191731 ni->type = AT_DATA;17201732 ni->name = NULL;17211733 ni->name_len = 0;17221722-17231734 /*17241735 * This sets up our little cheat allowing us to reuse the async read io17251736 * completion handler for directories.···1797180817981809 ntfs_debug("Attribute list attribute found in $MFT.");17991810 NInoSetAttrList(ni);18001800- if (ctx->attr->flags & ATTR_IS_ENCRYPTED ||18011801- ctx->attr->flags & ATTR_COMPRESSION_MASK ||18021802- ctx->attr->flags & ATTR_IS_SPARSE) {18111811+ a = ctx->attr;18121812+ if (a->flags & ATTR_IS_ENCRYPTED ||18131813+ a->flags & ATTR_COMPRESSION_MASK ||18141814+ a->flags & ATTR_IS_SPARSE) {18031815 ntfs_error(sb, "Attribute list attribute is "18041816 "compressed/encrypted/sparse. Not "18051817 "allowed. $MFT is corrupt. You should "···18081818 goto put_err_out;18091819 }18101820 /* Now allocate memory for the attribute list. */18111811- ni->attr_list_size = (u32)ntfs_attr_size(ctx->attr);18211821+ ni->attr_list_size = (u32)ntfs_attr_size(a);18121822 ni->attr_list = ntfs_malloc_nofs(ni->attr_list_size);18131823 if (!ni->attr_list) {18141824 ntfs_error(sb, "Not enough memory to allocate buffer "18151825 "for attribute list.");18161826 goto put_err_out;18171827 }18181818- if (ctx->attr->non_resident) {18281828+ if (a->non_resident) {18191829 NInoSetAttrListNonResident(ni);18201820- if (ctx->attr->data.non_resident.lowest_vcn) {18301830+ if (a->data.non_resident.lowest_vcn) {18211831 ntfs_error(sb, "Attribute list has non zero "18221832 "lowest_vcn. $MFT is corrupt. "18231833 "You should run chkdsk.");···18251835 }18261836 /* Setup the runlist. */18271837 ni->attr_list_rl.rl = ntfs_mapping_pairs_decompress(vol,18281828- ctx->attr, NULL);18381838+ a, NULL);18291839 if (IS_ERR(ni->attr_list_rl.rl)) {18301840 err = PTR_ERR(ni->attr_list_rl.rl);18311841 ni->attr_list_rl.rl = NULL;···18371847 /* Now load the attribute list. */18381848 if ((err = load_attribute_list(vol, &ni->attr_list_rl,18391849 ni->attr_list, ni->attr_list_size,18401840- sle64_to_cpu(ctx->attr->data.18501850+ sle64_to_cpu(a->data.18411851 non_resident.initialized_size)))) {18421852 ntfs_error(sb, "Failed to load attribute list "18431853 "attribute with error code %i.",···18451855 goto put_err_out;18461856 }18471857 } else /* if (!ctx.attr->non_resident) */ {18481848- if ((u8*)ctx->attr + le16_to_cpu(18491849- ctx->attr->data.resident.value_offset) +18581858+ if ((u8*)a + le16_to_cpu(18591859+ a->data.resident.value_offset) +18501860 le32_to_cpu(18511851- ctx->attr->data.resident.value_length) >18611861+ a->data.resident.value_length) >18521862 (u8*)ctx->mrec + vol->mft_record_size) {18531863 ntfs_error(sb, "Corrupt attribute list "18541864 "attribute.");18551865 goto put_err_out;18561866 }18571867 /* Now copy the attribute list. */18581858- memcpy(ni->attr_list, (u8*)ctx->attr + le16_to_cpu(18591859- ctx->attr->data.resident.value_offset),18681868+ memcpy(ni->attr_list, (u8*)a + le16_to_cpu(18691869+ a->data.resident.value_offset),18601870 le32_to_cpu(18611861- ctx->attr->data.resident.value_length));18711871+ a->data.resident.value_length));18621872 }18631873 /* The attribute list is now setup in memory. */18641874 /*···19241934 ntfs_attr_reinit_search_ctx(ctx);1925193519261936 /* Now load all attribute extents. */19271927- attr = NULL;19371937+ a = NULL;19281938 next_vcn = last_vcn = highest_vcn = 0;19291939 while (!(err = ntfs_attr_lookup(AT_DATA, NULL, 0, 0, next_vcn, NULL, 0,19301940 ctx))) {19311941 runlist_element *nrl;1932194219331943 /* Cache the current attribute. */19341934- attr = ctx->attr;19441944+ a = ctx->attr;19351945 /* $MFT must be non-resident. */19361936- if (!attr->non_resident) {19461946+ if (!a->non_resident) {19371947 ntfs_error(sb, "$MFT must be non-resident but a "19381948 "resident extent was found. $MFT is "19391949 "corrupt. Run chkdsk.");19401950 goto put_err_out;19411951 }19421952 /* $MFT must be uncompressed and unencrypted. */19431943- if (attr->flags & ATTR_COMPRESSION_MASK ||19441944- attr->flags & ATTR_IS_ENCRYPTED ||19451945- attr->flags & ATTR_IS_SPARSE) {19531953+ if (a->flags & ATTR_COMPRESSION_MASK ||19541954+ a->flags & ATTR_IS_ENCRYPTED ||19551955+ a->flags & ATTR_IS_SPARSE) {19461956 ntfs_error(sb, "$MFT must be uncompressed, "19471957 "non-sparse, and unencrypted but a "19481958 "compressed/sparse/encrypted extent "···19561966 * as we have exclusive access to the inode at this time and we19571967 * are a mount in progress task, too.19581968 */19591959- nrl = ntfs_mapping_pairs_decompress(vol, attr, ni->runlist.rl);19691969+ nrl = ntfs_mapping_pairs_decompress(vol, a, ni->runlist.rl);19601970 if (IS_ERR(nrl)) {19611971 ntfs_error(sb, "ntfs_mapping_pairs_decompress() "19621972 "failed with error code %ld. $MFT is "···1967197719681978 /* Are we in the first extent? */19691979 if (!next_vcn) {19701970- if (attr->data.non_resident.lowest_vcn) {19801980+ if (a->data.non_resident.lowest_vcn) {19711981 ntfs_error(sb, "First extent of $DATA "19721982 "attribute has non zero "19731983 "lowest_vcn. $MFT is corrupt. "···19761986 }19771987 /* Get the last vcn in the $DATA attribute. */19781988 last_vcn = sle64_to_cpu(19791979- attr->data.non_resident.allocated_size)19891989+ a->data.non_resident.allocated_size)19801990 >> vol->cluster_size_bits;19811991 /* Fill in the inode size. */19821992 vi->i_size = sle64_to_cpu(19831983- attr->data.non_resident.data_size);19841984- ni->initialized_size = sle64_to_cpu(attr->data.19851985- non_resident.initialized_size);19931993+ a->data.non_resident.data_size);19941994+ ni->initialized_size = sle64_to_cpu(19951995+ a->data.non_resident.initialized_size);19861996 ni->allocated_size = sle64_to_cpu(19871987- attr->data.non_resident.allocated_size);19971997+ a->data.non_resident.allocated_size);19881998 /*19891999 * Verify the number of mft records does not exceed19902000 * 2^32 - 1.···20412051 }2042205220432053 /* Get the lowest vcn for the next extent. */20442044- highest_vcn = sle64_to_cpu(attr->data.non_resident.highest_vcn);20542054+ highest_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn);20452055 next_vcn = highest_vcn + 1;2046205620472057 /* Only one extent or error, which we catch below. */···2050206020512061 /* Avoid endless loops due to corruption. */20522062 if (next_vcn < sle64_to_cpu(20532053- attr->data.non_resident.lowest_vcn)) {20632063+ a->data.non_resident.lowest_vcn)) {20542064 ntfs_error(sb, "$MFT has corrupt attribute list "20552065 "attribute. Run chkdsk.");20562066 goto put_err_out;···20612071 "$MFT is corrupt. Run chkdsk.");20622072 goto put_err_out;20632073 }20642064- if (!attr) {20742074+ if (!a) {20652075 ntfs_error(sb, "$MFT/$DATA attribute not found. $MFT is "20662076 "corrupt. Run chkdsk.");20672077 goto put_err_out;···22652275 seq_printf(sf, ",case_sensitive");22662276 if (NVolShowSystemFiles(vol))22672277 seq_printf(sf, ",show_sys_files");22782278+ if (!NVolSparseEnabled(vol))22792279+ seq_printf(sf, ",disable_sparse");22682280 for (i = 0; on_errors_arr[i].val; i++) {22692281 if (on_errors_arr[i].val & vol->on_errors)22702282 seq_printf(sf, ",errors=%s", on_errors_arr[i].str);···23032311 ntfs_volume *vol = ni->vol;23042312 ntfs_attr_search_ctx *ctx;23052313 MFT_RECORD *m;23142314+ ATTR_RECORD *a;23062315 const char *te = " Leaving file length out of sync with i_size.";23072316 int err;23082317···23402347 vi->i_ino, err);23412348 goto err_out;23422349 }23502350+ a = ctx->attr;23432351 /* If the size has not changed there is nothing to do. */23442344- if (ntfs_attr_size(ctx->attr) == i_size_read(vi))23522352+ if (ntfs_attr_size(a) == i_size_read(vi))23452353 goto done;23462354 // TODO: Implement the truncate...23472355 ntfs_error(vi->i_sb, "Inode size has changed but this is not "23482356 "implemented yet. Resetting inode size to old value. "23492357 " This is most likely a bug in the ntfs driver!");23502350- i_size_write(vi, ntfs_attr_size(ctx->attr)); 23582358+ i_size_write(vi, ntfs_attr_size(a)); 23512359done:23522360 ntfs_attr_put_search_ctx(ctx);23532361 unmap_mft_record(ni);···25092515 nt = utc2ntfs(vi->i_mtime);25102516 if (si->last_data_change_time != nt) {25112517 ntfs_debug("Updating mtime for inode 0x%lx: old = 0x%llx, "25122512- "new = 0x%llx", vi->i_ino,25182518+ "new = 0x%llx", vi->i_ino, (long long)25132519 sle64_to_cpu(si->last_data_change_time),25142514- sle64_to_cpu(nt));25202520+ (long long)sle64_to_cpu(nt));25152521 si->last_data_change_time = nt;25162522 modified = TRUE;25172523 }25182524 nt = utc2ntfs(vi->i_ctime);25192525 if (si->last_mft_change_time != nt) {25202526 ntfs_debug("Updating ctime for inode 0x%lx: old = 0x%llx, "25212521- "new = 0x%llx", vi->i_ino,25272527+ "new = 0x%llx", vi->i_ino, (long long)25222528 sle64_to_cpu(si->last_mft_change_time),25232523- sle64_to_cpu(nt));25292529+ (long long)sle64_to_cpu(nt));25242530 si->last_mft_change_time = nt;25252531 modified = TRUE;25262532 }···25282534 if (si->last_access_time != nt) {25292535 ntfs_debug("Updating atime for inode 0x%lx: old = 0x%llx, "25302536 "new = 0x%llx", vi->i_ino,25312531- sle64_to_cpu(si->last_access_time),25322532- sle64_to_cpu(nt));25372537+ (long long)sle64_to_cpu(si->last_access_time),25382538+ (long long)sle64_to_cpu(nt));25332539 si->last_access_time = nt;25342540 modified = TRUE;25352541 }
+5-2
fs/ntfs/inode.h
···22 * inode.h - Defines for inode structures NTFS Linux kernel driver. Part of33 * the Linux-NTFS project.44 *55- * Copyright (c) 2001-2004 Anton Altaparmakov55+ * Copyright (c) 2001-2005 Anton Altaparmakov66 * Copyright (c) 2002 Richard Russon77 *88 * This program/include file is free software; you can redistribute it and/or···4444 * fields already provided in the VFS inode.4545 */4646struct _ntfs_inode {4747+ rwlock_t size_lock; /* Lock serializing access to inode sizes. */4748 s64 initialized_size; /* Copy from the attribute record. */4849 s64 allocated_size; /* Copy from the attribute record. */4950 unsigned long state; /* NTFS specific flags describing this inode.···110109 u8 block_size_bits; /* Log2 of the above. */111110 u8 vcn_size_bits; /* Log2 of the above. */112111 } index;113113- struct { /* It is a compressed file or an attribute inode. */112112+ struct { /* It is a compressed/sparse file/attribute inode. */114113 s64 size; /* Copy of compressed_size from115114 $DATA. */116115 u32 block_size; /* Size of a compression block···166165 NI_Sparse, /* 1: Unnamed data attr is sparse (f).167166 1: Create sparse files by default (d).168167 1: Attribute is sparse (a). */168168+ NI_SparseDisabled, /* 1: May not create sparse regions. */169169 NI_TruncateFailed, /* 1: Last ntfs_truncate() call failed. */170170} ntfs_inode_state_bits;171171···219217NINO_FNS(Compressed)220218NINO_FNS(Encrypted)221219NINO_FNS(Sparse)220220+NINO_FNS(SparseDisabled)222221NINO_FNS(TruncateFailed)223222224223/*
+47-36
fs/ntfs/layout.h
···22 * layout.h - All NTFS associated on-disk structures. Part of the Linux-NTFS33 * project.44 *55- * Copyright (c) 2001-2004 Anton Altaparmakov55+ * Copyright (c) 2001-2005 Anton Altaparmakov66 * Copyright (c) 2002 Richard Russon77 *88 * This program/include file is free software; you can redistribute it and/or···547547 COLLATION_NTOFS_ULONG = const_cpu_to_le32(0x10),548548 COLLATION_NTOFS_SID = const_cpu_to_le32(0x11),549549 COLLATION_NTOFS_SECURITY_HASH = const_cpu_to_le32(0x12),550550- COLLATION_NTOFS_ULONGS = const_cpu_to_le32(0x13)550550+ COLLATION_NTOFS_ULONGS = const_cpu_to_le32(0x13),551551};552552553553typedef le32 COLLATION_RULE;554554555555/*556556 * The flags (32-bit) describing attribute properties in the attribute557557- * definition structure. FIXME: This information is from Regis's information558558- * and, according to him, it is not certain and probably incomplete.559559- * The INDEXABLE flag is fairly certainly correct as only the file name560560- * attribute has this flag set and this is the only attribute indexed in NT4.557557+ * definition structure. FIXME: This information is based on Regis's558558+ * information and, according to him, it is not certain and probably559559+ * incomplete. The INDEXABLE flag is fairly certainly correct as only the file560560+ * name attribute has this flag set and this is the only attribute indexed in561561+ * NT4.561562 */562563enum {563563- INDEXABLE = const_cpu_to_le32(0x02), /* Attribute can be564564- indexed. */565565- NEED_TO_REGENERATE = const_cpu_to_le32(0x40), /* Need to regenerate566566- during regeneration567567- phase. */568568- CAN_BE_NON_RESIDENT = const_cpu_to_le32(0x80), /* Attribute can be569569- non-resident. */564564+ ATTR_DEF_INDEXABLE = const_cpu_to_le32(0x02), /* Attribute can be565565+ indexed. */566566+ ATTR_DEF_MULTIPLE = const_cpu_to_le32(0x04), /* Attribute type567567+ can be present multiple times in the568568+ mft records of an inode. */569569+ ATTR_DEF_NOT_ZERO = const_cpu_to_le32(0x08), /* Attribute value570570+ must contain at least one non-zero571571+ byte. */572572+ ATTR_DEF_INDEXED_UNIQUE = const_cpu_to_le32(0x10), /* Attribute must be573573+ indexed and the attribute value must be574574+ unique for the attribute type in all of575575+ the mft records of an inode. */576576+ ATTR_DEF_NAMED_UNIQUE = const_cpu_to_le32(0x20), /* Attribute must be577577+ named and the name must be unique for578578+ the attribute type in all of the mft579579+ records of an inode. */580580+ ATTR_DEF_RESIDENT = const_cpu_to_le32(0x40), /* Attribute must be581581+ resident. */582582+ ATTR_DEF_ALWAYS_LOG = const_cpu_to_le32(0x80), /* Always log583583+ modifications to this attribute,584584+ regardless of whether it is resident or585585+ non-resident. Without this, only log586586+ modifications if the attribute is587587+ resident. */570588};571589572590typedef le32 ATTR_DEF_FLAGS;···767749 record header aligned to 8-byte boundary. */768750/* 34*/ u8 compression_unit; /* The compression unit expressed769751 as the log to the base 2 of the number of770770- clusters in a compression unit. 0 means not771771- compressed. (This effectively limits the752752+ clusters in a compression unit. 0 means not753753+ compressed. (This effectively limits the772754 compression unit size to be a power of two773773- clusters.) WinNT4 only uses a value of 4. */755755+ clusters.) WinNT4 only uses a value of 4.756756+ Sparse files also have this set to 4. */774757/* 35*/ u8 reserved[5]; /* Align to 8-byte boundary. */775758/* The sizes below are only used when lowest_vcn is zero, as otherwise it would776759 be difficult to keep them up-to-date.*/···791772 data_size. */792773/* sizeof(uncompressed attr) = 64*/793774/* 64*/ sle64 compressed_size; /* Byte size of the attribute794794- value after compression. Only present when795795- compressed. Always is a multiple of the796796- cluster size. Represents the actual amount of797797- disk space being used on the disk. */775775+ value after compression. Only present when776776+ compressed or sparse. Always is a multiple of777777+ the cluster size. Represents the actual amount778778+ of disk space being used on the disk. */798779/* sizeof(compressed attr) = 72*/799780 } __attribute__ ((__packed__)) non_resident;800781 } __attribute__ ((__packed__)) data;···853834 /* Note, this is a copy of the corresponding bit from the mft record,854835 telling us whether this file has a view index present (eg. object id855836 index, quota index, one of the security indexes or the encrypting856856- file system related indexes). */837837+ filesystem related indexes). */857838};858839859840typedef le32 FILE_ATTR_FLAGS;···936917 /* 56*/ le64 quota_charged; /* Byte size of the charge to937918 the quota for all streams of the file. Note: Is938919 zero if quotas are disabled. */939939- /* 64*/ le64 usn; /* Last update sequence number940940- of the file. This is a direct index into the941941- change (aka usn) journal file. It is zero if942942- the usn journal is disabled.943943- NOTE: To disable the journal need to delete944944- the journal file itself and to then walk the945945- whole mft and set all Usn entries in all mft946946- records to zero! (This can take a while!)947947- The journal is FILE_Extend/$UsnJrnl. Win2k948948- will recreate the journal and initiate949949- logging if necessary when mounting the950950- partition. This, in contrast to disabling the951951- journal is a very fast process, so the user952952- won't even notice it. */920920+ /* 64*/ leUSN usn; /* Last update sequence number921921+ of the file. This is a direct index into the922922+ transaction log file ($UsnJrnl). It is zero if923923+ the usn journal is disabled or this file has924924+ not been subject to logging yet. See usnjrnl.h925925+ for details. */953926 } __attribute__ ((__packed__)) v3;954927 /* sizeof() = 72 bytes (NTFS 3.x) */955928 } __attribute__ ((__packed__)) ver;···19041893 VOLUME_FLAGS_MASK = const_cpu_to_le16(0x803f),1905189419061895 /* To make our life easier when checking if we must mount read-only. */19071907- VOLUME_MUST_MOUNT_RO_MASK = const_cpu_to_le16(0x8037),18961896+ VOLUME_MUST_MOUNT_RO_MASK = const_cpu_to_le16(0x8027),19081897} __attribute__ ((__packed__));1909189819101899typedef le16 VOLUME_FLAGS;
+29-43
fs/ntfs/lcnalloc.c
···11/*22 * lcnalloc.c - Cluster (de)allocation code. Part of the Linux-NTFS project.33 *44- * Copyright (c) 2004 Anton Altaparmakov44+ * Copyright (c) 2004-2005 Anton Altaparmakov55 *66 * This program/include file is free software; you can redistribute it and/or77 * modify it under the terms of the GNU General Public License as published···6060 if (rl->lcn < 0)6161 continue;6262 err = ntfs_bitmap_clear_run(lcnbmp_vi, rl->lcn, rl->length);6363- if (unlikely(err && (!ret || ret == ENOMEM) && ret != err))6363+ if (unlikely(err && (!ret || ret == -ENOMEM) && ret != err))6464 ret = err;6565 }6666 ntfs_debug("Done.");···140140 LCN zone_start, zone_end, bmp_pos, bmp_initial_pos, last_read_pos, lcn;141141 LCN prev_lcn = 0, prev_run_len = 0, mft_zone_size;142142 s64 clusters;143143+ loff_t i_size;143144 struct inode *lcnbmp_vi;144145 runlist_element *rl = NULL;145146 struct address_space *mapping;···250249 clusters = count;251250 rlpos = rlsize = 0;252251 mapping = lcnbmp_vi->i_mapping;252252+ i_size = i_size_read(lcnbmp_vi);253253 while (1) {254254 ntfs_debug("Start of outer while loop: done_zones 0x%x, "255255 "search_zone %i, pass %i, zone_start 0x%llx, "···265263 last_read_pos = bmp_pos >> 3;266264 ntfs_debug("last_read_pos 0x%llx.",267265 (unsigned long long)last_read_pos);268268- if (last_read_pos > lcnbmp_vi->i_size) {266266+ if (last_read_pos > i_size) {269267 ntfs_debug("End of attribute reached. "270268 "Skipping to zone_pass_done.");271269 goto zone_pass_done;···289287 buf_size = last_read_pos & ~PAGE_CACHE_MASK;290288 buf = page_address(page) + buf_size;291289 buf_size = PAGE_CACHE_SIZE - buf_size;292292- if (unlikely(last_read_pos + buf_size > lcnbmp_vi->i_size))293293- buf_size = lcnbmp_vi->i_size - last_read_pos;290290+ if (unlikely(last_read_pos + buf_size > i_size))291291+ buf_size = i_size - last_read_pos;294292 buf_size <<= 3;295293 lcn = bmp_pos & 7;296296- bmp_pos &= ~7;294294+ bmp_pos &= ~(LCN)7;297295 ntfs_debug("Before inner while loop: buf_size %i, lcn 0x%llx, "298296 "bmp_pos 0x%llx, need_writeback %i.", buf_size,299297 (unsigned long long)lcn,···311309 (unsigned int)*byte);312310 /* Skip full bytes. */313311 if (*byte == 0xff) {314314- lcn = (lcn + 8) & ~7;312312+ lcn = (lcn + 8) & ~(LCN)7;315313 ntfs_debug("Continuing while loop 1.");316314 continue;317315 }···693691 if (zone == MFT_ZONE || mft_zone_size <= 0) {694692 ntfs_debug("No free clusters left, going to out.");695693 /* Really no more space left on device. */696696- err = ENOSPC;694694+ err = -ENOSPC;697695 goto out;698696 } /* zone == DATA_ZONE && mft_zone_size > 0 */699697 ntfs_debug("Shrinking mft zone.");···757755 if (rl) {758756 int err2;759757760760- if (err == ENOSPC)758758+ if (err == -ENOSPC)761759 ntfs_debug("Not enough space to complete allocation, "762762- "err ENOSPC, first free lcn 0x%llx, "760760+ "err -ENOSPC, first free lcn 0x%llx, "763761 "could allocate up to 0x%llx "764762 "clusters.",765763 (unsigned long long)rl[0].lcn,766766- (unsigned long long)count - clusters);764764+ (unsigned long long)(count - clusters));767765 /* Deallocate all allocated clusters. */768766 ntfs_debug("Attempting rollback...");769767 err2 = ntfs_cluster_free_from_rl_nolock(vol, rl);···775773 }776774 /* Free the runlist. */777775 ntfs_free(rl);778778- } else if (err == ENOSPC)779779- ntfs_debug("No space left at all, err = ENOSPC, "780780- "first free lcn = 0x%llx.",781781- (unsigned long long)vol->data1_zone_pos);776776+ } else if (err == -ENOSPC)777777+ ntfs_debug("No space left at all, err = -ENOSPC, first free "778778+ "lcn = 0x%llx.",779779+ (long long)vol->data1_zone_pos);782780 up_write(&vol->lcnbmp_lock);783781 return ERR_PTR(err);784782}···848846849847 total_freed = real_freed = 0;850848851851- /* This returns with ni->runlist locked for reading on success. */852852- rl = ntfs_find_vcn(ni, start_vcn, FALSE);849849+ down_read(&ni->runlist.lock);850850+ rl = ntfs_attr_find_vcn_nolock(ni, start_vcn, FALSE);853851 if (IS_ERR(rl)) {854852 if (!is_rollback)855853 ntfs_error(vol->sb, "Failed to find first runlist "···863861 ntfs_error(vol->sb, "First runlist element has "864862 "invalid lcn, aborting.");865863 err = -EIO;866866- goto unl_err_out;864864+ goto err_out;867865 }868866 /* Find the starting cluster inside the run that needs freeing. */869867 delta = start_vcn - rl->vcn;···881879 if (!is_rollback)882880 ntfs_error(vol->sb, "Failed to clear first run "883881 "(error %i), aborting.", err);884884- goto unl_err_out;882882+ goto err_out;885883 }886884 /* We have freed @to_free real clusters. */887885 real_freed = to_free;···901899 if (unlikely(rl->lcn < LCN_HOLE)) {902900 VCN vcn;903901904904- /*905905- * Attempt to map runlist, dropping runlist lock for906906- * the duration.907907- */902902+ /* Attempt to map runlist. */908903 vcn = rl->vcn;909909- up_read(&ni->runlist.lock);910910- err = ntfs_map_runlist(ni, vcn);911911- if (err) {912912- if (!is_rollback)913913- ntfs_error(vol->sb, "Failed to map "914914- "runlist fragment.");915915- if (err == -EINVAL || err == -ENOENT)916916- err = -EIO;917917- goto err_out;918918- }919919- /*920920- * This returns with ni->runlist locked for reading on921921- * success.922922- */923923- rl = ntfs_find_vcn(ni, vcn, FALSE);904904+ rl = ntfs_attr_find_vcn_nolock(ni, vcn, FALSE);924905 if (IS_ERR(rl)) {925906 err = PTR_ERR(rl);926907 if (!is_rollback)927927- ntfs_error(vol->sb, "Failed to find "908908+ ntfs_error(vol->sb, "Failed to map "909909+ "runlist fragment or "910910+ "failed to find "928911 "subsequent runlist "929912 "element.");930913 goto err_out;···922935 (unsigned long long)923936 rl->lcn);924937 err = -EIO;925925- goto unl_err_out;938938+ goto err_out;926939 }927940 }928941 /* The number of clusters in this run that need freeing. */···938951 if (!is_rollback)939952 ntfs_error(vol->sb, "Failed to clear "940953 "subsequent run.");941941- goto unl_err_out;954954+ goto err_out;942955 }943956 /* We have freed @to_free real clusters. */944957 real_freed += to_free;···959972 /* We are done. Return the number of actually freed clusters. */960973 ntfs_debug("Done.");961974 return real_freed;962962-unl_err_out:963963- up_read(&ni->runlist.lock);964975err_out:976976+ up_read(&ni->runlist.lock);965977 if (is_rollback)966978 return err;967979 /* If no real clusters were freed, no need to rollback. */
+6-5
fs/ntfs/logfile.c
···11/*22 * logfile.c - NTFS kernel journal handling. Part of the Linux-NTFS project.33 *44- * Copyright (c) 2002-2004 Anton Altaparmakov44+ * Copyright (c) 2002-2005 Anton Altaparmakov55 *66 * This program/include file is free software; you can redistribute it and/or77 * modify it under the terms of the GNU General Public License as published···410410}411411412412/**413413- * ntfs_ckeck_logfile - check in the journal if the volume is consistent413413+ * ntfs_check_logfile - check the journal for consistency414414 * @log_vi: struct inode of loaded journal $LogFile to check415415 *416416 * Check the $LogFile journal for consistency and return TRUE if it is···443443 /* An empty $LogFile must have been clean before it got emptied. */444444 if (NVolLogFileEmpty(vol))445445 goto is_empty;446446- size = log_vi->i_size;446446+ size = i_size_read(log_vi);447447 /* Make sure the file doesn't exceed the maximum allowed size. */448448 if (size > MaxLogFileSize)449449 size = MaxLogFileSize;···464464 * optimize log_page_size and log_page_bits into constants.465465 */466466 log_page_bits = generic_ffs(log_page_size) - 1;467467- size &= ~(log_page_size - 1);467467+ size &= ~(s64)(log_page_size - 1);468468 /*469469 * Ensure the log file is big enough to store at least the two restart470470 * pages and the minimum number of log record pages.···689689 if (!NVolLogFileEmpty(vol)) {690690 int err;691691692692- err = ntfs_attr_set(NTFS_I(log_vi), 0, log_vi->i_size, 0xff);692692+ err = ntfs_attr_set(NTFS_I(log_vi), 0, i_size_read(log_vi),693693+ 0xff);693694 if (unlikely(err)) {694695 ntfs_error(vol->sb, "Failed to fill $LogFile with "695696 "0xff bytes (error code %i).", err);
+155-72
fs/ntfs/mft.c
···11/**22 * mft.c - NTFS kernel mft record operations. Part of the Linux-NTFS project.33 *44- * Copyright (c) 2001-2004 Anton Altaparmakov44+ * Copyright (c) 2001-2005 Anton Altaparmakov55 * Copyright (c) 2002 Richard Russon66 *77 * This program/include file is free software; you can redistribute it and/or···4545 */4646static inline MFT_RECORD *map_mft_record_page(ntfs_inode *ni)4747{4848+ loff_t i_size;4849 ntfs_volume *vol = ni->vol;4950 struct inode *mft_vi = vol->mft_ino;5051 struct page *page;···6160 index = ni->mft_no << vol->mft_record_size_bits >> PAGE_CACHE_SHIFT;6261 ofs = (ni->mft_no << vol->mft_record_size_bits) & ~PAGE_CACHE_MASK;63626363+ i_size = i_size_read(mft_vi);6464 /* The maximum valid index into the page cache for $MFT's data. */6565- end_index = mft_vi->i_size >> PAGE_CACHE_SHIFT;6565+ end_index = i_size >> PAGE_CACHE_SHIFT;66666767 /* If the wanted index is out of bounds the mft record doesn't exist. */6868 if (unlikely(index >= end_index)) {6969- if (index > end_index || (mft_vi->i_size & ~PAGE_CACHE_MASK) <7070- ofs + vol->mft_record_size) {6969+ if (index > end_index || (i_size & ~PAGE_CACHE_MASK) < ofs +7070+ vol->mft_record_size) {7171 page = ERR_PTR(-ENOENT);7272 ntfs_error(vol->sb, "Attemt to read mft record 0x%lx, "7373 "which is beyond the end of the mft. "···287285 }288286 unmap_mft_record(ni);289287 ntfs_error(base_ni->vol->sb, "Found stale extent mft "290290- "reference! Corrupt file system. "288288+ "reference! Corrupt filesystem. "291289 "Run chkdsk.");292290 return ERR_PTR(-EIO);293291 }···318316 /* Verify the sequence number if it is present. */319317 if (seq_no && (le16_to_cpu(m->sequence_number) != seq_no)) {320318 ntfs_error(base_ni->vol->sb, "Found stale extent mft "321321- "reference! Corrupt file system. Run chkdsk.");319319+ "reference! Corrupt filesystem. Run chkdsk.");322320 destroy_ni = TRUE;323321 m = ERR_PTR(-EIO);324322 goto unm_err_out;···948946 na.name_len = 0;949947 na.type = AT_UNUSED;950948 /*951951- * For inode 0, i.e. $MFT itself, we cannot use ilookup5() from here or952952- * we deadlock because the inode is already locked by the kernel953953- * (fs/fs-writeback.c::__sync_single_inode()) and ilookup5() waits954954- * until the inode is unlocked before returning it and it never gets955955- * unlocked because ntfs_should_write_mft_record() never returns. )-:956956- * Fortunately, we have inode 0 pinned in icache for the duration of957957- * the mount so we can access it directly.949949+ * Optimize inode 0, i.e. $MFT itself, since we have it in memory and950950+ * we get here for it rather often.958951 */959952 if (!mft_no) {960953 /* Balance the below iput(). */961954 vi = igrab(mft_vi);962955 BUG_ON(vi != mft_vi);963963- } else964964- vi = ilookup5(sb, mft_no, (test_t)ntfs_test_inode, &na);956956+ } else {957957+ /*958958+ * Have to use ilookup5_nowait() since ilookup5() waits for the959959+ * inode lock which causes ntfs to deadlock when a concurrent960960+ * inode write via the inode dirty code paths and the page961961+ * dirty code path of the inode dirty code path when writing962962+ * $MFT occurs.963963+ */964964+ vi = ilookup5_nowait(sb, mft_no, (test_t)ntfs_test_inode, &na);965965+ }965966 if (vi) {966967 ntfs_debug("Base inode 0x%lx is in icache.", mft_no);967968 /* The inode is in icache. */···10191014 na.mft_no = MREF_LE(m->base_mft_record);10201015 ntfs_debug("Mft record 0x%lx is an extent record. Looking for base "10211016 "inode 0x%lx in icache.", mft_no, na.mft_no);10221022- vi = ilookup5(sb, na.mft_no, (test_t)ntfs_test_inode, &na);10171017+ if (!na.mft_no) {10181018+ /* Balance the below iput(). */10191019+ vi = igrab(mft_vi);10201020+ BUG_ON(vi != mft_vi);10211021+ } else10221022+ vi = ilookup5_nowait(sb, na.mft_no, (test_t)ntfs_test_inode,10231023+ &na);10231024 if (!vi) {10241025 /*10251026 * The base inode is not in icache, write this extent mft···11321121 ntfs_inode *base_ni)11331122{11341123 s64 pass_end, ll, data_pos, pass_start, ofs, bit;11241124+ unsigned long flags;11351125 struct address_space *mftbmp_mapping;11361126 u8 *buf, *byte;11371127 struct page *page;···11461134 * Set the end of the pass making sure we do not overflow the mft11471135 * bitmap.11481136 */11371137+ read_lock_irqsave(&NTFS_I(vol->mft_ino)->size_lock, flags);11491138 pass_end = NTFS_I(vol->mft_ino)->allocated_size >>11501139 vol->mft_record_size_bits;11401140+ read_unlock_irqrestore(&NTFS_I(vol->mft_ino)->size_lock, flags);11411141+ read_lock_irqsave(&NTFS_I(vol->mftbmp_ino)->size_lock, flags);11511142 ll = NTFS_I(vol->mftbmp_ino)->initialized_size << 3;11431143+ read_unlock_irqrestore(&NTFS_I(vol->mftbmp_ino)->size_lock, flags);11521144 if (pass_end > ll)11531145 pass_end = ll;11541146 pass = 1;···12791263{12801264 LCN lcn;12811265 s64 ll;12661266+ unsigned long flags;12821267 struct page *page;12831268 ntfs_inode *mft_ni, *mftbmp_ni;12841269 runlist_element *rl, *rl2 = NULL;···13011284 /*13021285 * Determine the last lcn of the mft bitmap. The allocated size of the13031286 * mft bitmap cannot be zero so we are ok to do this.13041304- * ntfs_find_vcn() returns the runlist locked on success.13051287 */13061306- rl = ntfs_find_vcn(mftbmp_ni, (mftbmp_ni->allocated_size - 1) >>13071307- vol->cluster_size_bits, TRUE);12881288+ down_write(&mftbmp_ni->runlist.lock);12891289+ read_lock_irqsave(&mftbmp_ni->size_lock, flags);12901290+ ll = mftbmp_ni->allocated_size;12911291+ read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);12921292+ rl = ntfs_attr_find_vcn_nolock(mftbmp_ni,12931293+ (ll - 1) >> vol->cluster_size_bits, TRUE);13081294 if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) {12951295+ up_write(&mftbmp_ni->runlist.lock);13091296 ntfs_error(vol->sb, "Failed to determine last allocated "13101297 "cluster of mft bitmap attribute.");13111311- if (!IS_ERR(rl)) {13121312- up_write(&mftbmp_ni->runlist.lock);12981298+ if (!IS_ERR(rl))13131299 ret = -EIO;13141314- } else13001300+ else13151301 ret = PTR_ERR(rl);13161302 return ret;13171303 }···14161396 BUG_ON(ll < rl2->vcn);14171397 BUG_ON(ll >= rl2->vcn + rl2->length);14181398 /* Get the size for the new mapping pairs array for this extent. */14191419- mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll);13991399+ mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll, -1);14201400 if (unlikely(mp_size <= 0)) {14211401 ntfs_error(vol->sb, "Get size for mapping pairs failed for "14221402 "mft bitmap attribute extent.");···14381418 // TODO: Deal with this by moving this extent to a new mft14391419 // record or by starting a new extent in a new mft record or by14401420 // moving other attributes out of this mft record.14211421+ // Note: It will need to be a special mft record and if none of14221422+ // those are available it gets rather complicated...14411423 ntfs_error(vol->sb, "Not enough space in this mft record to "14421424 "accomodate extended mft bitmap attribute "14431425 "extent. Cannot handle this yet.");···14501428 /* Generate the mapping pairs array directly into the attr record. */14511429 ret = ntfs_mapping_pairs_build(vol, (u8*)a +14521430 le16_to_cpu(a->data.non_resident.mapping_pairs_offset),14531453- mp_size, rl2, ll, NULL);14311431+ mp_size, rl2, ll, -1, NULL);14541432 if (unlikely(ret)) {14551433 ntfs_error(vol->sb, "Failed to build mapping pairs array for "14561434 "mft bitmap attribute.");···14801458 }14811459 a = ctx->attr;14821460 }14611461+ write_lock_irqsave(&mftbmp_ni->size_lock, flags);14831462 mftbmp_ni->allocated_size += vol->cluster_size;14841463 a->data.non_resident.allocated_size =14851464 cpu_to_sle64(mftbmp_ni->allocated_size);14651465+ write_unlock_irqrestore(&mftbmp_ni->size_lock, flags);14861466 /* Ensure the changes make it to disk. */14871467 flush_dcache_mft_record_page(ctx->ntfs_ino);14881468 mark_mft_record_dirty(ctx->ntfs_ino);···15001476 0, ctx)) {15011477 ntfs_error(vol->sb, "Failed to find last attribute extent of "15021478 "mft bitmap attribute.%s", es);14791479+ write_lock_irqsave(&mftbmp_ni->size_lock, flags);15031480 mftbmp_ni->allocated_size += vol->cluster_size;14811481+ write_unlock_irqrestore(&mftbmp_ni->size_lock, flags);15041482 ntfs_attr_put_search_ctx(ctx);15051483 unmap_mft_record(mft_ni);15061484 up_write(&mftbmp_ni->runlist.lock);···15381512 a->data.non_resident.mapping_pairs_offset),15391513 old_alen - le16_to_cpu(15401514 a->data.non_resident.mapping_pairs_offset),15411541- rl2, ll, NULL)) {15151515+ rl2, ll, -1, NULL)) {15421516 ntfs_error(vol->sb, "Failed to restore mapping pairs "15431517 "array.%s", es);15441518 NVolSetErrors(vol);···15761550static int ntfs_mft_bitmap_extend_initialized_nolock(ntfs_volume *vol)15771551{15781552 s64 old_data_size, old_initialized_size;15531553+ unsigned long flags;15791554 struct inode *mftbmp_vi;15801555 ntfs_inode *mft_ni, *mftbmp_ni;15811556 ntfs_attr_search_ctx *ctx;···16101583 goto put_err_out;16111584 }16121585 a = ctx->attr;16131613- old_data_size = mftbmp_vi->i_size;15861586+ write_lock_irqsave(&mftbmp_ni->size_lock, flags);15871587+ old_data_size = i_size_read(mftbmp_vi);16141588 old_initialized_size = mftbmp_ni->initialized_size;16151589 /*16161590 * We can simply update the initialized_size before filling the space···16211593 mftbmp_ni->initialized_size += 8;16221594 a->data.non_resident.initialized_size =16231595 cpu_to_sle64(mftbmp_ni->initialized_size);16241624- if (mftbmp_ni->initialized_size > mftbmp_vi->i_size) {16251625- mftbmp_vi->i_size = mftbmp_ni->initialized_size;15961596+ if (mftbmp_ni->initialized_size > old_data_size) {15971597+ i_size_write(mftbmp_vi, mftbmp_ni->initialized_size);16261598 a->data.non_resident.data_size =16271627- cpu_to_sle64(mftbmp_vi->i_size);15991599+ cpu_to_sle64(mftbmp_ni->initialized_size);16281600 }16011601+ write_unlock_irqrestore(&mftbmp_ni->size_lock, flags);16291602 /* Ensure the changes make it to disk. */16301603 flush_dcache_mft_record_page(ctx->ntfs_ino);16311604 mark_mft_record_dirty(ctx->ntfs_ino);···16651636 goto err_out;16661637 }16671638 a = ctx->attr;16391639+ write_lock_irqsave(&mftbmp_ni->size_lock, flags);16681640 mftbmp_ni->initialized_size = old_initialized_size;16691641 a->data.non_resident.initialized_size =16701642 cpu_to_sle64(old_initialized_size);16711671- if (mftbmp_vi->i_size != old_data_size) {16721672- mftbmp_vi->i_size = old_data_size;16431643+ if (i_size_read(mftbmp_vi) != old_data_size) {16441644+ i_size_write(mftbmp_vi, old_data_size);16731645 a->data.non_resident.data_size = cpu_to_sle64(old_data_size);16741646 }16471647+ write_unlock_irqrestore(&mftbmp_ni->size_lock, flags);16751648 flush_dcache_mft_record_page(ctx->ntfs_ino);16761649 mark_mft_record_dirty(ctx->ntfs_ino);16771650 ntfs_attr_put_search_ctx(ctx);16781651 unmap_mft_record(mft_ni);16521652+#ifdef DEBUG16531653+ read_lock_irqsave(&mftbmp_ni->size_lock, flags);16791654 ntfs_debug("Restored status of mftbmp: allocated_size 0x%llx, "16801655 "data_size 0x%llx, initialized_size 0x%llx.",16811656 (long long)mftbmp_ni->allocated_size,16821682- (long long)mftbmp_vi->i_size,16571657+ (long long)i_size_read(mftbmp_vi),16831658 (long long)mftbmp_ni->initialized_size);16591659+ read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);16601660+#endif /* DEBUG */16841661err_out:16851662 return ret;16861663}···17141679{17151680 LCN lcn;17161681 VCN old_last_vcn;17171717- s64 min_nr, nr, ll = 0;16821682+ s64 min_nr, nr, ll;16831683+ unsigned long flags;17181684 ntfs_inode *mft_ni;17191685 runlist_element *rl, *rl2;17201686 ntfs_attr_search_ctx *ctx = NULL;···17311695 * Determine the preferred allocation location, i.e. the last lcn of17321696 * the mft data attribute. The allocated size of the mft data17331697 * attribute cannot be zero so we are ok to do this.17341734- * ntfs_find_vcn() returns the runlist locked on success.17351698 */17361736- rl = ntfs_find_vcn(mft_ni, (mft_ni->allocated_size - 1) >>17371737- vol->cluster_size_bits, TRUE);16991699+ down_write(&mft_ni->runlist.lock);17001700+ read_lock_irqsave(&mft_ni->size_lock, flags);17011701+ ll = mft_ni->allocated_size;17021702+ read_unlock_irqrestore(&mft_ni->size_lock, flags);17031703+ rl = ntfs_attr_find_vcn_nolock(mft_ni,17041704+ (ll - 1) >> vol->cluster_size_bits, TRUE);17381705 if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) {17061706+ up_write(&mft_ni->runlist.lock);17391707 ntfs_error(vol->sb, "Failed to determine last allocated "17401708 "cluster of mft data attribute.");17411741- if (!IS_ERR(rl)) {17421742- up_write(&mft_ni->runlist.lock);17091709+ if (!IS_ERR(rl))17431710 ret = -EIO;17441744- } else17111711+ else17451712 ret = PTR_ERR(rl);17461713 return ret;17471714 }17481715 lcn = rl->lcn + rl->length;17491749- ntfs_debug("Last lcn of mft data attribute is 0x%llx.",17501750- (long long)lcn);17161716+ ntfs_debug("Last lcn of mft data attribute is 0x%llx.", (long long)lcn);17511717 /* Minimum allocation is one mft record worth of clusters. */17521718 min_nr = vol->mft_record_size >> vol->cluster_size_bits;17531719 if (!min_nr)···17591721 if (!nr)17601722 nr = min_nr;17611723 /* Ensure we do not go above 2^32-1 mft records. */17621762- if (unlikely((mft_ni->allocated_size +17631763- (nr << vol->cluster_size_bits)) >>17241724+ read_lock_irqsave(&mft_ni->size_lock, flags);17251725+ ll = mft_ni->allocated_size;17261726+ read_unlock_irqrestore(&mft_ni->size_lock, flags);17271727+ if (unlikely((ll + (nr << vol->cluster_size_bits)) >>17641728 vol->mft_record_size_bits >= (1ll << 32))) {17651729 nr = min_nr;17661766- if (unlikely((mft_ni->allocated_size +17671767- (nr << vol->cluster_size_bits)) >>17301730+ if (unlikely((ll + (nr << vol->cluster_size_bits)) >>17681731 vol->mft_record_size_bits >= (1ll << 32))) {17691732 ntfs_warning(vol->sb, "Cannot allocate mft record "17701733 "because the maximum number of inodes "···18111772 return PTR_ERR(rl);18121773 }18131774 mft_ni->runlist.rl = rl;18141814- ntfs_debug("Allocated %lli clusters.", nr);17751775+ ntfs_debug("Allocated %lli clusters.", (long long)nr);18151776 /* Find the last run in the new runlist. */18161777 for (; rl[1].length; rl++)18171778 ;···18471808 BUG_ON(ll < rl2->vcn);18481809 BUG_ON(ll >= rl2->vcn + rl2->length);18491810 /* Get the size for the new mapping pairs array for this extent. */18501850- mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll);18111811+ mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll, -1);18511812 if (unlikely(mp_size <= 0)) {18521813 ntfs_error(vol->sb, "Get size for mapping pairs failed for "18531814 "mft data attribute extent.");···18711832 // moving other attributes out of this mft record.18721833 // Note: Use the special reserved mft records and ensure that18731834 // this extent is not required to find the mft record in18741874- // question.18351835+ // question. If no free special records left we would need to18361836+ // move an existing record away, insert ours in its place, and18371837+ // then place the moved record into the newly allocated space18381838+ // and we would then need to update all references to this mft18391839+ // record appropriately. This is rather complicated...18751840 ntfs_error(vol->sb, "Not enough space in this mft record to "18761841 "accomodate extended mft data attribute "18771842 "extent. Cannot handle this yet.");···18861843 /* Generate the mapping pairs array directly into the attr record. */18871844 ret = ntfs_mapping_pairs_build(vol, (u8*)a +18881845 le16_to_cpu(a->data.non_resident.mapping_pairs_offset),18891889- mp_size, rl2, ll, NULL);18461846+ mp_size, rl2, ll, -1, NULL);18901847 if (unlikely(ret)) {18911848 ntfs_error(vol->sb, "Failed to build mapping pairs array of "18921849 "mft data attribute.");···19181875 }19191876 a = ctx->attr;19201877 }18781878+ write_lock_irqsave(&mft_ni->size_lock, flags);19211879 mft_ni->allocated_size += nr << vol->cluster_size_bits;19221880 a->data.non_resident.allocated_size =19231881 cpu_to_sle64(mft_ni->allocated_size);18821882+ write_unlock_irqrestore(&mft_ni->size_lock, flags);19241883 /* Ensure the changes make it to disk. */19251884 flush_dcache_mft_record_page(ctx->ntfs_ino);19261885 mark_mft_record_dirty(ctx->ntfs_ino);···19371892 CASE_SENSITIVE, rl[1].vcn, NULL, 0, ctx)) {19381893 ntfs_error(vol->sb, "Failed to find last attribute extent of "19391894 "mft data attribute.%s", es);18951895+ write_lock_irqsave(&mft_ni->size_lock, flags);19401896 mft_ni->allocated_size += nr << vol->cluster_size_bits;18971897+ write_unlock_irqrestore(&mft_ni->size_lock, flags);19411898 ntfs_attr_put_search_ctx(ctx);19421899 unmap_mft_record(mft_ni);19431900 up_write(&mft_ni->runlist.lock);···19681921 a->data.non_resident.mapping_pairs_offset),19691922 old_alen - le16_to_cpu(19701923 a->data.non_resident.mapping_pairs_offset),19711971- rl2, ll, NULL)) {19241924+ rl2, ll, -1, NULL)) {19721925 ntfs_error(vol->sb, "Failed to restore mapping pairs "19731926 "array.%s", es);19741927 NVolSetErrors(vol);···20381991 "reports this as corruption, please email "20391992 "linux-ntfs-dev@lists.sourceforge.net stating "20401993 "that you saw this message and that the "20412041- "modified file system created was corrupt. "19941994+ "modified filesystem created was corrupt. "20421995 "Thank you.");20431996 }20441997 /* Set the update sequence number to 1. */···20832036 */20842037static int ntfs_mft_record_format(const ntfs_volume *vol, const s64 mft_no)20852038{20392039+ loff_t i_size;20862040 struct inode *mft_vi = vol->mft_ino;20872041 struct page *page;20882042 MFT_RECORD *m;···20992051 index = mft_no << vol->mft_record_size_bits >> PAGE_CACHE_SHIFT;21002052 ofs = (mft_no << vol->mft_record_size_bits) & ~PAGE_CACHE_MASK;21012053 /* The maximum valid index into the page cache for $MFT's data. */21022102- end_index = mft_vi->i_size >> PAGE_CACHE_SHIFT;20542054+ i_size = i_size_read(mft_vi);20552055+ end_index = i_size >> PAGE_CACHE_SHIFT;21032056 if (unlikely(index >= end_index)) {21042057 if (unlikely(index > end_index || ofs + vol->mft_record_size >=21052105- (mft_vi->i_size & ~PAGE_CACHE_MASK))) {20582058+ (i_size & ~PAGE_CACHE_MASK))) {21062059 ntfs_error(vol->sb, "Tried to format non-existing mft "21072060 "record 0x%llx.", (long long)mft_no);21082061 return -ENOENT;···22372188 ntfs_inode *base_ni, MFT_RECORD **mrec)22382189{22392190 s64 ll, bit, old_data_initialized, old_data_size;21912191+ unsigned long flags;22402192 struct inode *vi;22412193 struct page *page;22422194 ntfs_inode *mft_ni, *mftbmp_ni, *ni;···22872237 * the first 24 mft records as they are special and whilst they may not22882238 * be in use, we do not allocate from them.22892239 */22402240+ read_lock_irqsave(&mft_ni->size_lock, flags);22902241 ll = mft_ni->initialized_size >> vol->mft_record_size_bits;22912291- if (mftbmp_ni->initialized_size << 3 > ll &&22922292- mftbmp_ni->initialized_size > 3) {22422242+ read_unlock_irqrestore(&mft_ni->size_lock, flags);22432243+ read_lock_irqsave(&mftbmp_ni->size_lock, flags);22442244+ old_data_initialized = mftbmp_ni->initialized_size;22452245+ read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);22462246+ if (old_data_initialized << 3 > ll && old_data_initialized > 3) {22932247 bit = ll;22942248 if (bit < 24)22952249 bit = 24;···23082254 * mft record that we can allocate.23092255 * Note: The smallest mft record we allocate is mft record 24.23102256 */23112311- bit = mftbmp_ni->initialized_size << 3;22572257+ bit = old_data_initialized << 3;23122258 if (unlikely(bit >= (1ll << 32)))23132259 goto max_err_out;22602260+ read_lock_irqsave(&mftbmp_ni->size_lock, flags);22612261+ old_data_size = mftbmp_ni->allocated_size;23142262 ntfs_debug("Status of mftbmp before extension: allocated_size 0x%llx, "23152263 "data_size 0x%llx, initialized_size 0x%llx.",23162316- (long long)mftbmp_ni->allocated_size,23172317- (long long)vol->mftbmp_ino->i_size,23182318- (long long)mftbmp_ni->initialized_size);23192319- if (mftbmp_ni->initialized_size + 8 > mftbmp_ni->allocated_size) {22642264+ (long long)old_data_size,22652265+ (long long)i_size_read(vol->mftbmp_ino),22662266+ (long long)old_data_initialized);22672267+ read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);22682268+ if (old_data_initialized + 8 > old_data_size) {23202269 /* Need to extend bitmap by one more cluster. */23212270 ntfs_debug("mftbmp: initialized_size + 8 > allocated_size.");23222271 err = ntfs_mft_bitmap_extend_allocation_nolock(vol);···23272270 up_write(&vol->mftbmp_lock);23282271 goto err_out;23292272 }22732273+#ifdef DEBUG22742274+ read_lock_irqsave(&mftbmp_ni->size_lock, flags);23302275 ntfs_debug("Status of mftbmp after allocation extension: "23312276 "allocated_size 0x%llx, data_size 0x%llx, "23322277 "initialized_size 0x%llx.",23332278 (long long)mftbmp_ni->allocated_size,23342334- (long long)vol->mftbmp_ino->i_size,22792279+ (long long)i_size_read(vol->mftbmp_ino),23352280 (long long)mftbmp_ni->initialized_size);22812281+ read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);22822282+#endif /* DEBUG */23362283 }23372284 /*23382285 * We now have sufficient allocated space, extend the initialized_size···23482287 up_write(&vol->mftbmp_lock);23492288 goto err_out;23502289 }22902290+#ifdef DEBUG22912291+ read_lock_irqsave(&mftbmp_ni->size_lock, flags);23512292 ntfs_debug("Status of mftbmp after initialized extention: "23522293 "allocated_size 0x%llx, data_size 0x%llx, "23532294 "initialized_size 0x%llx.",23542295 (long long)mftbmp_ni->allocated_size,23552355- (long long)vol->mftbmp_ino->i_size,22962296+ (long long)i_size_read(vol->mftbmp_ino),23562297 (long long)mftbmp_ni->initialized_size);22982298+ read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);22992299+#endif /* DEBUG */23572300 ntfs_debug("Found free record (#3), bit 0x%llx.", (long long)bit);23582301found_free_rec:23592302 /* @bit is the found free mft record, allocate it in the mft bitmap. */···23792314 * parallel allocation could allocate the same mft record as this one.23802315 */23812316 ll = (bit + 1) << vol->mft_record_size_bits;23822382- if (ll <= mft_ni->initialized_size) {23172317+ read_lock_irqsave(&mft_ni->size_lock, flags);23182318+ old_data_initialized = mft_ni->initialized_size;23192319+ read_unlock_irqrestore(&mft_ni->size_lock, flags);23202320+ if (ll <= old_data_initialized) {23832321 ntfs_debug("Allocated mft record already initialized.");23842322 goto mft_rec_already_initialized;23852323 }···23932325 * actually traversed more than once when a freshly formatted volume is23942326 * first written to so it optimizes away nicely in the common case.23952327 */23282328+ read_lock_irqsave(&mft_ni->size_lock, flags);23962329 ntfs_debug("Status of mft data before extension: "23972330 "allocated_size 0x%llx, data_size 0x%llx, "23982331 "initialized_size 0x%llx.",23992332 (long long)mft_ni->allocated_size,24002400- (long long)vol->mft_ino->i_size,23332333+ (long long)i_size_read(vol->mft_ino),24012334 (long long)mft_ni->initialized_size);24022335 while (ll > mft_ni->allocated_size) {23362336+ read_unlock_irqrestore(&mft_ni->size_lock, flags);24032337 err = ntfs_mft_data_extend_allocation_nolock(vol);24042338 if (unlikely(err)) {24052339 ntfs_error(vol->sb, "Failed to extend mft data "24062340 "allocation.");24072341 goto undo_mftbmp_alloc_nolock;24082342 }23432343+ read_lock_irqsave(&mft_ni->size_lock, flags);24092344 ntfs_debug("Status of mft data after allocation extension: "24102345 "allocated_size 0x%llx, data_size 0x%llx, "24112346 "initialized_size 0x%llx.",24122347 (long long)mft_ni->allocated_size,24132413- (long long)vol->mft_ino->i_size,23482348+ (long long)i_size_read(vol->mft_ino),24142349 (long long)mft_ni->initialized_size);24152350 }23512351+ read_unlock_irqrestore(&mft_ni->size_lock, flags);24162352 /*24172353 * Extend mft data initialized size (and data size of course) to reach24182354 * the allocated mft record, formatting the mft records allong the way.···24242352 * needed by ntfs_mft_record_format(). We will update the attribute24252353 * record itself in one fell swoop later on.24262354 */23552355+ write_lock_irqsave(&mft_ni->size_lock, flags);24272356 old_data_initialized = mft_ni->initialized_size;24282357 old_data_size = vol->mft_ino->i_size;24292358 while (ll > mft_ni->initialized_size) {···24332360 new_initialized_size = mft_ni->initialized_size +24342361 vol->mft_record_size;24352362 mft_no = mft_ni->initialized_size >> vol->mft_record_size_bits;24362436- if (new_initialized_size > vol->mft_ino->i_size)24372437- vol->mft_ino->i_size = new_initialized_size;23632363+ if (new_initialized_size > i_size_read(vol->mft_ino))23642364+ i_size_write(vol->mft_ino, new_initialized_size);23652365+ write_unlock_irqrestore(&mft_ni->size_lock, flags);24382366 ntfs_debug("Initializing mft record 0x%llx.",24392367 (long long)mft_no);24402368 err = ntfs_mft_record_format(vol, mft_no);···24432369 ntfs_error(vol->sb, "Failed to format mft record.");24442370 goto undo_data_init;24452371 }23722372+ write_lock_irqsave(&mft_ni->size_lock, flags);24462373 mft_ni->initialized_size = new_initialized_size;24472374 }23752375+ write_unlock_irqrestore(&mft_ni->size_lock, flags);24482376 record_formatted = TRUE;24492377 /* Update the mft data attribute record to reflect the new sizes. */24502378 m = map_mft_record(mft_ni);···24722396 goto undo_data_init;24732397 }24742398 a = ctx->attr;23992399+ read_lock_irqsave(&mft_ni->size_lock, flags);24752400 a->data.non_resident.initialized_size =24762401 cpu_to_sle64(mft_ni->initialized_size);24772477- a->data.non_resident.data_size = cpu_to_sle64(vol->mft_ino->i_size);24022402+ a->data.non_resident.data_size =24032403+ cpu_to_sle64(i_size_read(vol->mft_ino));24042404+ read_unlock_irqrestore(&mft_ni->size_lock, flags);24782405 /* Ensure the changes make it to disk. */24792406 flush_dcache_mft_record_page(ctx->ntfs_ino);24802407 mark_mft_record_dirty(ctx->ntfs_ino);24812408 ntfs_attr_put_search_ctx(ctx);24822409 unmap_mft_record(mft_ni);24102410+ read_lock_irqsave(&mft_ni->size_lock, flags);24832411 ntfs_debug("Status of mft data after mft record initialization: "24842412 "allocated_size 0x%llx, data_size 0x%llx, "24852413 "initialized_size 0x%llx.",24862414 (long long)mft_ni->allocated_size,24872487- (long long)vol->mft_ino->i_size,24152415+ (long long)i_size_read(vol->mft_ino),24882416 (long long)mft_ni->initialized_size);24892489- BUG_ON(vol->mft_ino->i_size > mft_ni->allocated_size);24902490- BUG_ON(mft_ni->initialized_size > vol->mft_ino->i_size);24172417+ BUG_ON(i_size_read(vol->mft_ino) > mft_ni->allocated_size);24182418+ BUG_ON(mft_ni->initialized_size > i_size_read(vol->mft_ino));24192419+ read_unlock_irqrestore(&mft_ni->size_lock, flags);24912420mft_rec_already_initialized:24922421 /*24932422 * We can finally drop the mft bitmap lock as the mft data attribute···27332652 *mrec = m;27342653 return ni;27352654undo_data_init:26552655+ write_lock_irqsave(&mft_ni->size_lock, flags);27362656 mft_ni->initialized_size = old_data_initialized;27372737- vol->mft_ino->i_size = old_data_size;26572657+ i_size_write(vol->mft_ino, old_data_size);26582658+ write_unlock_irqrestore(&mft_ni->size_lock, flags);27382659 goto undo_mftbmp_alloc_nolock;27392660undo_mftbmp_alloc:27402661 down_write(&vol->mftbmp_lock);
+30-4
fs/ntfs/namei.c
···153153 ntfs_error(vol->sb, "ntfs_iget(0x%lx) failed with "154154 "error code %li.", dent_ino,155155 PTR_ERR(dent_inode));156156- if (name)157157- kfree(name);156156+ kfree(name);158157 /* Return the error code. */159158 return (struct dentry *)dent_inode;160159 }···379380 * Return the dentry of the parent directory on success or the error code on380381 * error (IS_ERR() is true).381382 */382382-struct dentry *ntfs_get_parent(struct dentry *child_dent)383383+static struct dentry *ntfs_get_parent(struct dentry *child_dent)383384{384385 struct inode *vi = child_dent->d_inode;385386 ntfs_inode *ni = NTFS_I(vi);···464465 *465466 * Return the dentry on success or the error code on error (IS_ERR() is true).466467 */467467-struct dentry *ntfs_get_dentry(struct super_block *sb, void *fh)468468+static struct dentry *ntfs_get_dentry(struct super_block *sb, void *fh)468469{469470 struct inode *vi;470471 struct dentry *dent;···495496 ntfs_debug("Done for inode 0x%lx, generation 0x%x.", ino, gen);496497 return dent;497498}499499+500500+/**501501+ * Export operations allowing NFS exporting of mounted NTFS partitions.502502+ *503503+ * We use the default ->decode_fh() and ->encode_fh() for now. Note that they504504+ * use 32 bits to store the inode number which is an unsigned long so on 64-bit505505+ * architectures is usually 64 bits so it would all fail horribly on huge506506+ * volumes. I guess we need to define our own encode and decode fh functions507507+ * that store 64-bit inode numbers at some point but for now we will ignore the508508+ * problem...509509+ *510510+ * We also use the default ->get_name() helper (used by ->decode_fh() via511511+ * fs/exportfs/expfs.c::find_exported_dentry()) as that is completely fs512512+ * independent.513513+ *514514+ * The default ->get_parent() just returns -EACCES so we have to provide our515515+ * own and the default ->get_dentry() is incompatible with NTFS due to not516516+ * allowing the inode number 0 which is used in NTFS for the system file $MFT517517+ * and due to using iget() whereas NTFS needs ntfs_iget().518518+ */519519+struct export_operations ntfs_export_ops = {520520+ .get_parent = ntfs_get_parent, /* Find the parent of a given521521+ directory. */522522+ .get_dentry = ntfs_get_dentry, /* Find a dentry for the inode523523+ given a file handle524524+ sub-fragment. */525525+};
+7-1
fs/ntfs/ntfs.h
···22 * ntfs.h - Defines for NTFS Linux kernel driver. Part of the Linux-NTFS33 * project.44 *55- * Copyright (c) 2001-2004 Anton Altaparmakov55+ * Copyright (c) 2001-2005 Anton Altaparmakov66 * Copyright (C) 2002 Richard Russon77 *88 * This program/include file is free software; you can redistribute it and/or···3131#include <linux/fs.h>3232#include <linux/nls.h>3333#include <linux/smp.h>3434+#include <linux/pagemap.h>34353536#include "types.h"3637#include "volume.h"···4241 NTFS_BLOCK_SIZE_BITS = 9,4342 NTFS_SB_MAGIC = 0x5346544e, /* 'NTFS' */4443 NTFS_MAX_NAME_LEN = 255,4444+ NTFS_MAX_ATTR_NAME_LEN = 255,4545+ NTFS_MAX_CLUSTER_SIZE = 64 * 1024, /* 64kiB */4646+ NTFS_MAX_PAGES_PER_CLUSTER = NTFS_MAX_CLUSTER_SIZE / PAGE_CACHE_SIZE,4547} NTFS_CONSTANTS;46484749/* Global variables. */···68646965extern struct file_operations ntfs_empty_file_ops;7066extern struct inode_operations ntfs_empty_inode_ops;6767+6868+extern struct export_operations ntfs_export_ops;71697270/**7371 * NTFS_SB - return the ntfs volume given a vfs super block
+198-80
fs/ntfs/runlist.c
···11/**22 * runlist.c - NTFS runlist handling code. Part of the Linux-NTFS project.33 *44- * Copyright (c) 2001-2004 Anton Altaparmakov44+ * Copyright (c) 2001-2005 Anton Altaparmakov55 * Copyright (c) 2002 Richard Russon66 *77 * This program/include file is free software; you can redistribute it and/or···5959 *6060 * As the runlists grow, more memory will be required. To prevent the6161 * kernel having to allocate and reallocate large numbers of small bits of6262- * memory, this function returns and entire page of memory.6262+ * memory, this function returns an entire page of memory.6363 *6464 * It is up to the caller to serialize access to the runlist @rl.6565 *···113113 BUG_ON(!dst);114114 BUG_ON(!src);115115116116- if ((dst->lcn < 0) || (src->lcn < 0)) /* Are we merging holes? */116116+ if ((dst->lcn < 0) || (src->lcn < 0)) { /* Are we merging holes? */117117+ if (dst->lcn == LCN_HOLE && src->lcn == LCN_HOLE)118118+ return TRUE;117119 return FALSE;120120+ }118121 if ((dst->lcn + dst->length) != src->lcn) /* Are the runs contiguous? */119122 return FALSE;120123 if ((dst->vcn + dst->length) != src->vcn) /* Are the runs misaligned? */···858855 if (!attr->data.non_resident.lowest_vcn) {859856 VCN max_cluster;860857861861- max_cluster = (sle64_to_cpu(858858+ max_cluster = ((sle64_to_cpu(862859 attr->data.non_resident.allocated_size) +863860 vol->cluster_size - 1) >>864864- vol->cluster_size_bits;861861+ vol->cluster_size_bits) - 1;865862 /*866866- * If there is a difference between the highest_vcn and the867867- * highest cluster, the runlist is either corrupt or, more868868- * likely, there are more extents following this one.863863+ * A highest_vcn of zero means this is a single extent864864+ * attribute so simply terminate the runlist with LCN_ENOENT).869865 */870870- if (deltaxcn < --max_cluster) {871871- ntfs_debug("More extents to follow; deltaxcn = 0x%llx, "872872- "max_cluster = 0x%llx",873873- (unsigned long long)deltaxcn,874874- (unsigned long long)max_cluster);875875- rl[rlpos].vcn = vcn;876876- vcn += rl[rlpos].length = max_cluster - deltaxcn;877877- rl[rlpos].lcn = LCN_RL_NOT_MAPPED;878878- rlpos++;879879- } else if (unlikely(deltaxcn > max_cluster)) {880880- ntfs_error(vol->sb, "Corrupt attribute. deltaxcn = "881881- "0x%llx, max_cluster = 0x%llx",882882- (unsigned long long)deltaxcn,883883- (unsigned long long)max_cluster);884884- goto mpa_err;866866+ if (deltaxcn) {867867+ /*868868+ * If there is a difference between the highest_vcn and869869+ * the highest cluster, the runlist is either corrupt870870+ * or, more likely, there are more extents following871871+ * this one.872872+ */873873+ if (deltaxcn < max_cluster) {874874+ ntfs_debug("More extents to follow; deltaxcn "875875+ "= 0x%llx, max_cluster = "876876+ "0x%llx",877877+ (unsigned long long)deltaxcn,878878+ (unsigned long long)879879+ max_cluster);880880+ rl[rlpos].vcn = vcn;881881+ vcn += rl[rlpos].length = max_cluster -882882+ deltaxcn;883883+ rl[rlpos].lcn = LCN_RL_NOT_MAPPED;884884+ rlpos++;885885+ } else if (unlikely(deltaxcn > max_cluster)) {886886+ ntfs_error(vol->sb, "Corrupt attribute. "887887+ "deltaxcn = 0x%llx, "888888+ "max_cluster = 0x%llx",889889+ (unsigned long long)deltaxcn,890890+ (unsigned long long)891891+ max_cluster);892892+ goto mpa_err;893893+ }885894 }886895 rl[rlpos].lcn = LCN_ENOENT;887896 } else /* Not the base extent. There may be more extents to follow. */···933918 *934919 * It is up to the caller to serialize access to the runlist @rl.935920 *936936- * Since lcns must be >= 0, we use negative return values with special meaning:921921+ * Since lcns must be >= 0, we use negative return codes with special meaning:937922 *938938- * Return value Meaning / Description923923+ * Return code Meaning / Description939924 * ==================================================940940- * -1 = LCN_HOLE Hole / not allocated on disk.941941- * -2 = LCN_RL_NOT_MAPPED This is part of the runlist which has not been942942- * inserted into the runlist yet.943943- * -3 = LCN_ENOENT There is no such vcn in the attribute.925925+ * LCN_HOLE Hole / not allocated on disk.926926+ * LCN_RL_NOT_MAPPED This is part of the runlist which has not been927927+ * inserted into the runlist yet.928928+ * LCN_ENOENT There is no such vcn in the attribute.944929 *945930 * Locking: - The caller must have locked the runlist (for reading or writing).946946- * - This function does not touch the lock.931931+ * - This function does not touch the lock, nor does it modify the932932+ * runlist.947933 */948934LCN ntfs_rl_vcn_to_lcn(const runlist_element *rl, const VCN vcn)949935{···978962 return rl[i].lcn;979963 /* Just in case... We could replace this with BUG() some day. */980964 return LCN_ENOENT;965965+}966966+967967+#ifdef NTFS_RW968968+969969+/**970970+ * ntfs_rl_find_vcn_nolock - find a vcn in a runlist971971+ * @rl: runlist to search972972+ * @vcn: vcn to find973973+ *974974+ * Find the virtual cluster number @vcn in the runlist @rl and return the975975+ * address of the runlist element containing the @vcn on success.976976+ *977977+ * Return NULL if @rl is NULL or @vcn is in an unmapped part/out of bounds of978978+ * the runlist.979979+ *980980+ * Locking: The runlist must be locked on entry.981981+ */982982+runlist_element *ntfs_rl_find_vcn_nolock(runlist_element *rl, const VCN vcn)983983+{984984+ BUG_ON(vcn < 0);985985+ if (unlikely(!rl || vcn < rl[0].vcn))986986+ return NULL;987987+ while (likely(rl->length)) {988988+ if (unlikely(vcn < rl[1].vcn)) {989989+ if (likely(rl->lcn >= LCN_HOLE))990990+ return rl;991991+ return NULL;992992+ }993993+ rl++;994994+ }995995+ if (likely(rl->lcn == LCN_ENOENT))996996+ return rl;997997+ return NULL;981998}9829999831000/**···1048999 * ntfs_get_size_for_mapping_pairs - get bytes needed for mapping pairs array10491000 * @vol: ntfs volume (needed for the ntfs version)10501001 * @rl: locked runlist to determine the size of the mapping pairs of10511051- * @start_vcn: vcn at which to start the mapping pairs array10021002+ * @first_vcn: first vcn which to include in the mapping pairs array10031003+ * @last_vcn: last vcn which to include in the mapping pairs array10521004 *10531005 * Walk the locked runlist @rl and calculate the size in bytes of the mapping10541054- * pairs array corresponding to the runlist @rl, starting at vcn @start_vcn.10061006+ * pairs array corresponding to the runlist @rl, starting at vcn @first_vcn and10071007+ * finishing with vcn @last_vcn.10081008+ *10091009+ * A @last_vcn of -1 means end of runlist and in that case the size of the10101010+ * mapping pairs array corresponding to the runlist starting at vcn @first_vcn10111011+ * and finishing at the end of the runlist is determined.10121012+ *10551013 * This for example allows us to allocate a buffer of the right size when10561014 * building the mapping pairs array.10571015 *···10741018 * remains locked throughout, and is left locked upon return.10751019 */10761020int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol,10771077- const runlist_element *rl, const VCN start_vcn)10211021+ const runlist_element *rl, const VCN first_vcn,10221022+ const VCN last_vcn)10781023{10791024 LCN prev_lcn;10801025 int rls;10261026+ BOOL the_end = FALSE;1081102710821082- BUG_ON(start_vcn < 0);10281028+ BUG_ON(first_vcn < 0);10291029+ BUG_ON(last_vcn < -1);10301030+ BUG_ON(last_vcn >= 0 && first_vcn > last_vcn);10831031 if (!rl) {10841084- BUG_ON(start_vcn);10321032+ BUG_ON(first_vcn);10331033+ BUG_ON(last_vcn > 0);10851034 return 1;10861035 }10871087- /* Skip to runlist element containing @start_vcn. */10881088- while (rl->length && start_vcn >= rl[1].vcn)10361036+ /* Skip to runlist element containing @first_vcn. */10371037+ while (rl->length && first_vcn >= rl[1].vcn)10891038 rl++;10901090- if ((!rl->length && start_vcn > rl->vcn) || start_vcn < rl->vcn)10391039+ if (unlikely((!rl->length && first_vcn > rl->vcn) ||10401040+ first_vcn < rl->vcn))10911041 return -EINVAL;10921042 prev_lcn = 0;10931043 /* Always need the termining zero byte. */10941044 rls = 1;10951045 /* Do the first partial run if present. */10961096- if (start_vcn > rl->vcn) {10971097- s64 delta;10461046+ if (first_vcn > rl->vcn) {10471047+ s64 delta, length = rl->length;1098104810991049 /* We know rl->length != 0 already. */11001100- if (rl->length < 0 || rl->lcn < LCN_HOLE)10501050+ if (unlikely(length < 0 || rl->lcn < LCN_HOLE))11011051 goto err_out;11021102- delta = start_vcn - rl->vcn;10521052+ /*10531053+ * If @stop_vcn is given and finishes inside this run, cap the10541054+ * run length.10551055+ */10561056+ if (unlikely(last_vcn >= 0 && rl[1].vcn > last_vcn)) {10571057+ s64 s1 = last_vcn + 1;10581058+ if (unlikely(rl[1].vcn > s1))10591059+ length = s1 - rl->vcn;10601060+ the_end = TRUE;10611061+ }10621062+ delta = first_vcn - rl->vcn;11031063 /* Header byte + length. */11041104- rls += 1 + ntfs_get_nr_significant_bytes(rl->length - delta);10641064+ rls += 1 + ntfs_get_nr_significant_bytes(length - delta);11051065 /*11061066 * If the logical cluster number (lcn) denotes a hole and we11071067 * are on NTFS 3.0+, we don't store it at all, i.e. we need···11251053 * Note: this assumes that on NTFS 1.2-, holes are stored with11261054 * an lcn of -1 and not a delta_lcn of -1 (unless both are -1).11271055 */11281128- if (rl->lcn >= 0 || vol->major_ver < 3) {10561056+ if (likely(rl->lcn >= 0 || vol->major_ver < 3)) {11291057 prev_lcn = rl->lcn;11301130- if (rl->lcn >= 0)10581058+ if (likely(rl->lcn >= 0))11311059 prev_lcn += delta;11321060 /* Change in lcn. */11331061 rls += ntfs_get_nr_significant_bytes(prev_lcn);···11361064 rl++;11371065 }11381066 /* Do the full runs. */11391139- for (; rl->length; rl++) {11401140- if (rl->length < 0 || rl->lcn < LCN_HOLE)10671067+ for (; rl->length && !the_end; rl++) {10681068+ s64 length = rl->length;10691069+10701070+ if (unlikely(length < 0 || rl->lcn < LCN_HOLE))11411071 goto err_out;10721072+ /*10731073+ * If @stop_vcn is given and finishes inside this run, cap the10741074+ * run length.10751075+ */10761076+ if (unlikely(last_vcn >= 0 && rl[1].vcn > last_vcn)) {10771077+ s64 s1 = last_vcn + 1;10781078+ if (unlikely(rl[1].vcn > s1))10791079+ length = s1 - rl->vcn;10801080+ the_end = TRUE;10811081+ }11421082 /* Header byte + length. */11431143- rls += 1 + ntfs_get_nr_significant_bytes(rl->length);10831083+ rls += 1 + ntfs_get_nr_significant_bytes(length);11441084 /*11451085 * If the logical cluster number (lcn) denotes a hole and we11461086 * are on NTFS 3.0+, we don't store it at all, i.e. we need···11601076 * Note: this assumes that on NTFS 1.2-, holes are stored with11611077 * an lcn of -1 and not a delta_lcn of -1 (unless both are -1).11621078 */11631163- if (rl->lcn >= 0 || vol->major_ver < 3) {10791079+ if (likely(rl->lcn >= 0 || vol->major_ver < 3)) {11641080 /* Change in lcn. */11651081 rls += ntfs_get_nr_significant_bytes(rl->lcn -11661082 prev_lcn);···1203111912041120 i = 0;12051121 do {12061206- if (dst > dst_max)11221122+ if (unlikely(dst > dst_max))12071123 goto err_out;12081124 *dst++ = l & 0xffll;12091125 l >>= 8;···12121128 j = (n >> 8 * (i - 1)) & 0xff;12131129 /* If the sign bit is wrong, we need an extra byte. */12141130 if (n < 0 && j >= 0) {12151215- if (dst > dst_max)11311131+ if (unlikely(dst > dst_max))12161132 goto err_out;12171133 i++;12181134 *dst = (s8)-1;12191135 } else if (n > 0 && j < 0) {12201220- if (dst > dst_max)11361136+ if (unlikely(dst > dst_max))12211137 goto err_out;12221138 i++;12231139 *dst = (s8)0;···12331149 * @dst: destination buffer to which to write the mapping pairs array12341150 * @dst_len: size of destination buffer @dst in bytes12351151 * @rl: locked runlist for which to build the mapping pairs array12361236- * @start_vcn: vcn at which to start the mapping pairs array11521152+ * @first_vcn: first vcn which to include in the mapping pairs array11531153+ * @last_vcn: last vcn which to include in the mapping pairs array12371154 * @stop_vcn: first vcn outside destination buffer on success or -ENOSPC12381155 *12391156 * Create the mapping pairs array from the locked runlist @rl, starting at vcn12401240- * @start_vcn and save the array in @dst. @dst_len is the size of @dst in12411241- * bytes and it should be at least equal to the value obtained by calling12421242- * ntfs_get_size_for_mapping_pairs().11571157+ * @first_vcn and finishing with vcn @last_vcn and save the array in @dst.11581158+ * @dst_len is the size of @dst in bytes and it should be at least equal to the11591159+ * value obtained by calling ntfs_get_size_for_mapping_pairs().11601160+ *11611161+ * A @last_vcn of -1 means end of runlist and in that case the mapping pairs11621162+ * array corresponding to the runlist starting at vcn @first_vcn and finishing11631163+ * at the end of the runlist is created.12431164 *12441165 * If @rl is NULL, just write a single terminator byte to @dst.12451166 *···12531164 * been filled with all the mapping pairs that will fit, thus it can be treated12541165 * as partial success, in that a new attribute extent needs to be created or12551166 * the next extent has to be used and the mapping pairs build has to be12561256- * continued with @start_vcn set to *@stop_vcn.11671167+ * continued with @first_vcn set to *@stop_vcn.12571168 *12581169 * Return 0 on success and -errno on error. The following error codes are12591170 * defined:···12671178 */12681179int ntfs_mapping_pairs_build(const ntfs_volume *vol, s8 *dst,12691180 const int dst_len, const runlist_element *rl,12701270- const VCN start_vcn, VCN *const stop_vcn)11811181+ const VCN first_vcn, const VCN last_vcn, VCN *const stop_vcn)12711182{12721183 LCN prev_lcn;12731184 s8 *dst_max, *dst_next;12741185 int err = -ENOSPC;11861186+ BOOL the_end = FALSE;12751187 s8 len_len, lcn_len;1276118812771277- BUG_ON(start_vcn < 0);11891189+ BUG_ON(first_vcn < 0);11901190+ BUG_ON(last_vcn < -1);11911191+ BUG_ON(last_vcn >= 0 && first_vcn > last_vcn);12781192 BUG_ON(dst_len < 1);12791193 if (!rl) {12801280- BUG_ON(start_vcn);11941194+ BUG_ON(first_vcn);11951195+ BUG_ON(last_vcn > 0);12811196 if (stop_vcn)12821197 *stop_vcn = 0;12831198 /* Terminator byte. */12841199 *dst = 0;12851200 return 0;12861201 }12871287- /* Skip to runlist element containing @start_vcn. */12881288- while (rl->length && start_vcn >= rl[1].vcn)12021202+ /* Skip to runlist element containing @first_vcn. */12031203+ while (rl->length && first_vcn >= rl[1].vcn)12891204 rl++;12901290- if ((!rl->length && start_vcn > rl->vcn) || start_vcn < rl->vcn)12051205+ if (unlikely((!rl->length && first_vcn > rl->vcn) ||12061206+ first_vcn < rl->vcn))12911207 return -EINVAL;12921208 /*12931209 * @dst_max is used for bounds checking in···13011207 dst_max = dst + dst_len - 1;13021208 prev_lcn = 0;13031209 /* Do the first partial run if present. */13041304- if (start_vcn > rl->vcn) {13051305- s64 delta;12101210+ if (first_vcn > rl->vcn) {12111211+ s64 delta, length = rl->length;1306121213071213 /* We know rl->length != 0 already. */13081308- if (rl->length < 0 || rl->lcn < LCN_HOLE)12141214+ if (unlikely(length < 0 || rl->lcn < LCN_HOLE))13091215 goto err_out;13101310- delta = start_vcn - rl->vcn;12161216+ /*12171217+ * If @stop_vcn is given and finishes inside this run, cap the12181218+ * run length.12191219+ */12201220+ if (unlikely(last_vcn >= 0 && rl[1].vcn > last_vcn)) {12211221+ s64 s1 = last_vcn + 1;12221222+ if (unlikely(rl[1].vcn > s1))12231223+ length = s1 - rl->vcn;12241224+ the_end = TRUE;12251225+ }12261226+ delta = first_vcn - rl->vcn;13111227 /* Write length. */13121228 len_len = ntfs_write_significant_bytes(dst + 1, dst_max,13131313- rl->length - delta);13141314- if (len_len < 0)12291229+ length - delta);12301230+ if (unlikely(len_len < 0))13151231 goto size_err;13161232 /*13171233 * If the logical cluster number (lcn) denotes a hole and we···13321228 * case on NT4. - We assume that we just need to write the lcn13331229 * change until someone tells us otherwise... (AIA)13341230 */13351335- if (rl->lcn >= 0 || vol->major_ver < 3) {12311231+ if (likely(rl->lcn >= 0 || vol->major_ver < 3)) {13361232 prev_lcn = rl->lcn;13371337- if (rl->lcn >= 0)12331233+ if (likely(rl->lcn >= 0))13381234 prev_lcn += delta;13391235 /* Write change in lcn. */13401236 lcn_len = ntfs_write_significant_bytes(dst + 1 +13411237 len_len, dst_max, prev_lcn);13421342- if (lcn_len < 0)12381238+ if (unlikely(lcn_len < 0))13431239 goto size_err;13441240 } else13451241 lcn_len = 0;13461242 dst_next = dst + len_len + lcn_len + 1;13471347- if (dst_next > dst_max)12431243+ if (unlikely(dst_next > dst_max))13481244 goto size_err;13491245 /* Update header byte. */13501246 *dst = lcn_len << 4 | len_len;···13541250 rl++;13551251 }13561252 /* Do the full runs. */13571357- for (; rl->length; rl++) {13581358- if (rl->length < 0 || rl->lcn < LCN_HOLE)12531253+ for (; rl->length && !the_end; rl++) {12541254+ s64 length = rl->length;12551255+12561256+ if (unlikely(length < 0 || rl->lcn < LCN_HOLE))13591257 goto err_out;12581258+ /*12591259+ * If @stop_vcn is given and finishes inside this run, cap the12601260+ * run length.12611261+ */12621262+ if (unlikely(last_vcn >= 0 && rl[1].vcn > last_vcn)) {12631263+ s64 s1 = last_vcn + 1;12641264+ if (unlikely(rl[1].vcn > s1))12651265+ length = s1 - rl->vcn;12661266+ the_end = TRUE;12671267+ }13601268 /* Write length. */13611269 len_len = ntfs_write_significant_bytes(dst + 1, dst_max,13621362- rl->length);13631363- if (len_len < 0)12701270+ length);12711271+ if (unlikely(len_len < 0))13641272 goto size_err;13651273 /*13661274 * If the logical cluster number (lcn) denotes a hole and we···13831267 * case on NT4. - We assume that we just need to write the lcn13841268 * change until someone tells us otherwise... (AIA)13851269 */13861386- if (rl->lcn >= 0 || vol->major_ver < 3) {12701270+ if (likely(rl->lcn >= 0 || vol->major_ver < 3)) {13871271 /* Write change in lcn. */13881272 lcn_len = ntfs_write_significant_bytes(dst + 1 +13891273 len_len, dst_max, rl->lcn - prev_lcn);13901390- if (lcn_len < 0)12741274+ if (unlikely(lcn_len < 0))13911275 goto size_err;13921276 prev_lcn = rl->lcn;13931277 } else13941278 lcn_len = 0;13951279 dst_next = dst + len_len + lcn_len + 1;13961396- if (dst_next > dst_max)12801280+ if (unlikely(dst_next > dst_max))13971281 goto size_err;13981282 /* Update header byte. */13991283 *dst = lcn_len << 4 | len_len;···15521436 ntfs_debug("Done.");15531437 return 0;15541438}14391439+14401440+#endif /* NTFS_RW */
+13-3
fs/ntfs/runlist.h
···22 * runlist.h - Defines for runlist handling in NTFS Linux kernel driver.33 * Part of the Linux-NTFS project.44 *55- * Copyright (c) 2001-2004 Anton Altaparmakov55+ * Copyright (c) 2001-2005 Anton Altaparmakov66 * Copyright (c) 2002 Richard Russon77 *88 * This program/include file is free software; you can redistribute it and/or···6666 LCN_HOLE = -1, /* Keep this as highest value or die! */6767 LCN_RL_NOT_MAPPED = -2,6868 LCN_ENOENT = -3,6969+ LCN_ENOMEM = -4,7070+ LCN_EIO = -5,6971} LCN_SPECIAL_VALUES;70727173extern runlist_element *ntfs_runlists_merge(runlist_element *drl,···78767977extern LCN ntfs_rl_vcn_to_lcn(const runlist_element *rl, const VCN vcn);80787979+#ifdef NTFS_RW8080+8181+extern runlist_element *ntfs_rl_find_vcn_nolock(runlist_element *rl,8282+ const VCN vcn);8383+8184extern int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol,8282- const runlist_element *rl, const VCN start_vcn);8585+ const runlist_element *rl, const VCN first_vcn,8686+ const VCN last_vcn);83878488extern int ntfs_mapping_pairs_build(const ntfs_volume *vol, s8 *dst,8589 const int dst_len, const runlist_element *rl,8686- const VCN start_vcn, VCN *const stop_vcn);9090+ const VCN first_vcn, const VCN last_vcn, VCN *const stop_vcn);87918892extern int ntfs_rl_truncate_nolock(const ntfs_volume *vol,8993 runlist *const runlist, const s64 new_length);9494+9595+#endif /* NTFS_RW */90969197#endif /* _LINUX_NTFS_RUNLIST_H */
+542-150
fs/ntfs/super.c
···11/*22 * super.c - NTFS kernel super block handling. Part of the Linux-NTFS project.33 *44- * Copyright (c) 2001-2004 Anton Altaparmakov44+ * Copyright (c) 2001-2005 Anton Altaparmakov55 * Copyright (c) 2001,2002 Richard Russon66 *77 * This program/include file is free software; you can redistribute it and/or···3434#include "sysctl.h"3535#include "logfile.h"3636#include "quota.h"3737+#include "usnjrnl.h"3738#include "dir.h"3839#include "debug.h"3940#include "index.h"4041#include "aops.h"4242+#include "layout.h"4143#include "malloc.h"4244#include "ntfs.h"43454444-/* Number of mounted file systems which have compression enabled. */4646+/* Number of mounted filesystems which have compression enabled. */4547static unsigned long ntfs_nr_compression_users;46484749/* A global default upcase table and a corresponding reference count. */···104102 gid_t gid = (gid_t)-1;105103 mode_t fmask = (mode_t)-1, dmask = (mode_t)-1;106104 int mft_zone_multiplier = -1, on_errors = -1;107107- int show_sys_files = -1, case_sensitive = -1;105105+ int show_sys_files = -1, case_sensitive = -1, disable_sparse = -1;108106 struct nls_table *nls_map = NULL, *old_nls;109107110108 /* I am lazy... (-8 */···164162 else NTFS_GETOPT_WITH_DEFAULT("sloppy", sloppy, TRUE)165163 else NTFS_GETOPT_BOOL("show_sys_files", show_sys_files)166164 else NTFS_GETOPT_BOOL("case_sensitive", case_sensitive)165165+ else NTFS_GETOPT_BOOL("disable_sparse", disable_sparse)167166 else NTFS_GETOPT_OPTIONS_ARRAY("errors", on_errors,168167 on_errors_arr)169168 else if (!strcmp(p, "posix") || !strcmp(p, "show_inodes"))···293290 NVolSetCaseSensitive(vol);294291 else295292 NVolClearCaseSensitive(vol);293293+ }294294+ if (disable_sparse != -1) {295295+ if (disable_sparse)296296+ NVolClearSparseEnabled(vol);297297+ else {298298+ if (!NVolSparseEnabled(vol) &&299299+ vol->major_ver && vol->major_ver < 3)300300+ ntfs_warning(vol->sb, "Not enabling sparse "301301+ "support due to NTFS volume "302302+ "version %i.%i (need at least "303303+ "version 3.0).", vol->major_ver,304304+ vol->minor_ver);305305+ else306306+ NVolSetSparseEnabled(vol);307307+ }296308 }297309 return TRUE;298310needs_arg:···498480 NVolSetErrors(vol);499481 return -EROFS;500482 }483483+ if (!ntfs_stamp_usnjrnl(vol)) {484484+ ntfs_error(sb, "Failed to stamp transation log "485485+ "($UsnJrnl)%s", es);486486+ NVolSetErrors(vol);487487+ return -EROFS;488488+ }501489 } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) {502490 /* Remounting read-only. */503491 if (!NVolErrors(vol)) {···540516{541517 /*542518 * Check that checksum == sum of u32 values from b to the checksum543543- * field. If checksum is zero, no checking is done.519519+ * field. If checksum is zero, no checking is done. We will work when520520+ * the checksum test fails, since some utilities update the boot sector521521+ * ignoring the checksum which leaves the checksum out-of-date. We522522+ * report a warning if this is the case.544523 */545545- if ((void*)b < (void*)&b->checksum && b->checksum) {524524+ if ((void*)b < (void*)&b->checksum && b->checksum && !silent) {546525 le32 *u;547526 u32 i;548527549528 for (i = 0, u = (le32*)b; u < (le32*)(&b->checksum); ++u)550529 i += le32_to_cpup(u);551530 if (le32_to_cpu(b->checksum) != i)552552- goto not_ntfs;531531+ ntfs_warning(sb, "Invalid boot sector checksum.");553532 }554533 /* Check OEMidentifier is "NTFS " */555534 if (b->oem_id != magicNTFS)···568541 default:569542 goto not_ntfs;570543 }571571- /* Check the cluster size is not above 65536 bytes. */544544+ /* Check the cluster size is not above the maximum (64kiB). */572545 if ((u32)le16_to_cpu(b->bpb.bytes_per_sector) *573573- b->bpb.sectors_per_cluster > 0x10000)546546+ b->bpb.sectors_per_cluster > NTFS_MAX_CLUSTER_SIZE)574547 goto not_ntfs;575548 /* Check reserved/unused fields are really zero. */576549 if (le16_to_cpu(b->bpb.reserved_sectors) ||···602575 * many BIOSes will refuse to boot from a bootsector if the magic is603576 * incorrect, so we emit a warning.604577 */605605- if (!silent && b->end_of_sector_marker != cpu_to_le16(0xaa55))578578+ if (!silent && b->end_of_sector_marker != const_cpu_to_le16(0xaa55))606579 ntfs_warning(sb, "Invalid end of sector marker.");607580 return TRUE;608581not_ntfs:···994967 tmp_ni = NTFS_I(tmp_ino);995968 /* The $MFTMirr, like the $MFT is multi sector transfer protected. */996969 NInoSetMstProtected(tmp_ni);970970+ NInoSetSparseDisabled(tmp_ni);997971 /*998972 * Set up our little cheat allowing us to reuse the async read io999973 * completion handler for directories.···1018990 */1019991static BOOL check_mft_mirror(ntfs_volume *vol)1020992{10211021- unsigned long index;1022993 struct super_block *sb = vol->sb;1023994 ntfs_inode *mirr_ni;1024995 struct page *mft_page, *mirr_page;1025996 u8 *kmft, *kmirr;1026997 runlist_element *rl, rl2[2];998998+ pgoff_t index;1027999 int mrecs_per_page, i;1028100010291001 ntfs_debug("Entering.");···11501122 /* ntfs_check_logfile() will have displayed error output. */11511123 return FALSE;11521124 }11251125+ NInoSetSparseDisabled(NTFS_I(tmp_ino));11531126 vol->logfile_ino = tmp_ino;11541127 ntfs_debug("Done.");11551128 return TRUE;11291129+}11301130+11311131+#define NTFS_HIBERFIL_HEADER_SIZE 409611321132+11331133+/**11341134+ * check_windows_hibernation_status - check if Windows is suspended on a volume11351135+ * @vol: ntfs super block of device to check11361136+ *11371137+ * Check if Windows is hibernated on the ntfs volume @vol. This is done by11381138+ * looking for the file hiberfil.sys in the root directory of the volume. If11391139+ * the file is not present Windows is definitely not suspended.11401140+ *11411141+ * If hiberfil.sys exists and is less than 4kiB in size it means Windows is11421142+ * definitely suspended (this volume is not the system volume). Caveat: on a11431143+ * system with many volumes it is possible that the < 4kiB check is bogus but11441144+ * for now this should do fine.11451145+ *11461146+ * If hiberfil.sys exists and is larger than 4kiB in size, we need to read the11471147+ * hiberfil header (which is the first 4kiB). If this begins with "hibr",11481148+ * Windows is definitely suspended. If it is completely full of zeroes,11491149+ * Windows is definitely not hibernated. Any other case is treated as if11501150+ * Windows is suspended. This caters for the above mentioned caveat of a11511151+ * system with many volumes where no "hibr" magic would be present and there is11521152+ * no zero header.11531153+ *11541154+ * Return 0 if Windows is not hibernated on the volume, >0 if Windows is11551155+ * hibernated on the volume, and -errno on error.11561156+ */11571157+static int check_windows_hibernation_status(ntfs_volume *vol)11581158+{11591159+ MFT_REF mref;11601160+ struct inode *vi;11611161+ ntfs_inode *ni;11621162+ struct page *page;11631163+ u32 *kaddr, *kend;11641164+ ntfs_name *name = NULL;11651165+ int ret = 1;11661166+ static const ntfschar hiberfil[13] = { const_cpu_to_le16('h'),11671167+ const_cpu_to_le16('i'), const_cpu_to_le16('b'),11681168+ const_cpu_to_le16('e'), const_cpu_to_le16('r'),11691169+ const_cpu_to_le16('f'), const_cpu_to_le16('i'),11701170+ const_cpu_to_le16('l'), const_cpu_to_le16('.'),11711171+ const_cpu_to_le16('s'), const_cpu_to_le16('y'),11721172+ const_cpu_to_le16('s'), 0 };11731173+11741174+ ntfs_debug("Entering.");11751175+ /*11761176+ * Find the inode number for the hibernation file by looking up the11771177+ * filename hiberfil.sys in the root directory.11781178+ */11791179+ down(&vol->root_ino->i_sem);11801180+ mref = ntfs_lookup_inode_by_name(NTFS_I(vol->root_ino), hiberfil, 12,11811181+ &name);11821182+ up(&vol->root_ino->i_sem);11831183+ if (IS_ERR_MREF(mref)) {11841184+ ret = MREF_ERR(mref);11851185+ /* If the file does not exist, Windows is not hibernated. */11861186+ if (ret == -ENOENT) {11871187+ ntfs_debug("hiberfil.sys not present. Windows is not "11881188+ "hibernated on the volume.");11891189+ return 0;11901190+ }11911191+ /* A real error occured. */11921192+ ntfs_error(vol->sb, "Failed to find inode number for "11931193+ "hiberfil.sys.");11941194+ return ret;11951195+ }11961196+ /* We do not care for the type of match that was found. */11971197+ kfree(name);11981198+ /* Get the inode. */11991199+ vi = ntfs_iget(vol->sb, MREF(mref));12001200+ if (IS_ERR(vi) || is_bad_inode(vi)) {12011201+ if (!IS_ERR(vi))12021202+ iput(vi);12031203+ ntfs_error(vol->sb, "Failed to load hiberfil.sys.");12041204+ return IS_ERR(vi) ? PTR_ERR(vi) : -EIO;12051205+ }12061206+ if (unlikely(i_size_read(vi) < NTFS_HIBERFIL_HEADER_SIZE)) {12071207+ ntfs_debug("hiberfil.sys is smaller than 4kiB (0x%llx). "12081208+ "Windows is hibernated on the volume. This "12091209+ "is not the system volume.", i_size_read(vi));12101210+ goto iput_out;12111211+ }12121212+ ni = NTFS_I(vi);12131213+ page = ntfs_map_page(vi->i_mapping, 0);12141214+ if (IS_ERR(page)) {12151215+ ntfs_error(vol->sb, "Failed to read from hiberfil.sys.");12161216+ ret = PTR_ERR(page);12171217+ goto iput_out;12181218+ }12191219+ kaddr = (u32*)page_address(page);12201220+ if (*(le32*)kaddr == const_cpu_to_le32(0x72626968)/*'hibr'*/) {12211221+ ntfs_debug("Magic \"hibr\" found in hiberfil.sys. Windows is "12221222+ "hibernated on the volume. This is the "12231223+ "system volume.");12241224+ goto unm_iput_out;12251225+ }12261226+ kend = kaddr + NTFS_HIBERFIL_HEADER_SIZE/sizeof(*kaddr);12271227+ do {12281228+ if (unlikely(*kaddr)) {12291229+ ntfs_debug("hiberfil.sys is larger than 4kiB "12301230+ "(0x%llx), does not contain the "12311231+ "\"hibr\" magic, and does not have a "12321232+ "zero header. Windows is hibernated "12331233+ "on the volume. This is not the "12341234+ "system volume.", i_size_read(vi));12351235+ goto unm_iput_out;12361236+ }12371237+ } while (++kaddr < kend);12381238+ ntfs_debug("hiberfil.sys contains a zero header. Windows is not "12391239+ "hibernated on the volume. This is the system "12401240+ "volume.");12411241+ ret = 0;12421242+unm_iput_out:12431243+ ntfs_unmap_page(page);12441244+iput_out:12451245+ iput(vi);12461246+ return ret;11561247}1157124811581249/**···13221175 return FALSE;13231176 }13241177 /* We do not care for the type of match that was found. */13251325- if (name)13261326- kfree(name);11781178+ kfree(name);13271179 /* Get the inode. */13281180 tmp_ino = ntfs_iget(vol->sb, MREF(mref));13291181 if (IS_ERR(tmp_ino) || is_bad_inode(tmp_ino)) {···13441198}1345119913461200/**12011201+ * load_and_init_usnjrnl - load and setup the transaction log if present12021202+ * @vol: ntfs super block describing device whose usnjrnl file to load12031203+ *12041204+ * Return TRUE on success or FALSE on error.12051205+ *12061206+ * If $UsnJrnl is not present or in the process of being disabled, we set12071207+ * NVolUsnJrnlStamped() and return success.12081208+ *12091209+ * If the $UsnJrnl $DATA/$J attribute has a size equal to the lowest valid usn,12101210+ * i.e. transaction logging has only just been enabled or the journal has been12111211+ * stamped and nothing has been logged since, we also set NVolUsnJrnlStamped()12121212+ * and return success.12131213+ */12141214+static BOOL load_and_init_usnjrnl(ntfs_volume *vol)12151215+{12161216+ MFT_REF mref;12171217+ struct inode *tmp_ino;12181218+ ntfs_inode *tmp_ni;12191219+ struct page *page;12201220+ ntfs_name *name = NULL;12211221+ USN_HEADER *uh;12221222+ static const ntfschar UsnJrnl[9] = { const_cpu_to_le16('$'),12231223+ const_cpu_to_le16('U'), const_cpu_to_le16('s'),12241224+ const_cpu_to_le16('n'), const_cpu_to_le16('J'),12251225+ const_cpu_to_le16('r'), const_cpu_to_le16('n'),12261226+ const_cpu_to_le16('l'), 0 };12271227+ static ntfschar Max[5] = { const_cpu_to_le16('$'),12281228+ const_cpu_to_le16('M'), const_cpu_to_le16('a'),12291229+ const_cpu_to_le16('x'), 0 };12301230+ static ntfschar J[3] = { const_cpu_to_le16('$'),12311231+ const_cpu_to_le16('J'), 0 };12321232+12331233+ ntfs_debug("Entering.");12341234+ /*12351235+ * Find the inode number for the transaction log file by looking up the12361236+ * filename $UsnJrnl in the extended system files directory $Extend.12371237+ */12381238+ down(&vol->extend_ino->i_sem);12391239+ mref = ntfs_lookup_inode_by_name(NTFS_I(vol->extend_ino), UsnJrnl, 8,12401240+ &name);12411241+ up(&vol->extend_ino->i_sem);12421242+ if (IS_ERR_MREF(mref)) {12431243+ /*12441244+ * If the file does not exist, transaction logging is disabled,12451245+ * just return success.12461246+ */12471247+ if (MREF_ERR(mref) == -ENOENT) {12481248+ ntfs_debug("$UsnJrnl not present. Volume does not "12491249+ "have transaction logging enabled.");12501250+not_enabled:12511251+ /*12521252+ * No need to try to stamp the transaction log if12531253+ * transaction logging is not enabled.12541254+ */12551255+ NVolSetUsnJrnlStamped(vol);12561256+ return TRUE;12571257+ }12581258+ /* A real error occured. */12591259+ ntfs_error(vol->sb, "Failed to find inode number for "12601260+ "$UsnJrnl.");12611261+ return FALSE;12621262+ }12631263+ /* We do not care for the type of match that was found. */12641264+ kfree(name);12651265+ /* Get the inode. */12661266+ tmp_ino = ntfs_iget(vol->sb, MREF(mref));12671267+ if (unlikely(IS_ERR(tmp_ino) || is_bad_inode(tmp_ino))) {12681268+ if (!IS_ERR(tmp_ino))12691269+ iput(tmp_ino);12701270+ ntfs_error(vol->sb, "Failed to load $UsnJrnl.");12711271+ return FALSE;12721272+ }12731273+ vol->usnjrnl_ino = tmp_ino;12741274+ /*12751275+ * If the transaction log is in the process of being deleted, we can12761276+ * ignore it.12771277+ */12781278+ if (unlikely(vol->vol_flags & VOLUME_DELETE_USN_UNDERWAY)) {12791279+ ntfs_debug("$UsnJrnl in the process of being disabled. "12801280+ "Volume does not have transaction logging "12811281+ "enabled.");12821282+ goto not_enabled;12831283+ }12841284+ /* Get the $DATA/$Max attribute. */12851285+ tmp_ino = ntfs_attr_iget(vol->usnjrnl_ino, AT_DATA, Max, 4);12861286+ if (IS_ERR(tmp_ino)) {12871287+ ntfs_error(vol->sb, "Failed to load $UsnJrnl/$DATA/$Max "12881288+ "attribute.");12891289+ return FALSE;12901290+ }12911291+ vol->usnjrnl_max_ino = tmp_ino;12921292+ if (unlikely(i_size_read(tmp_ino) < sizeof(USN_HEADER))) {12931293+ ntfs_error(vol->sb, "Found corrupt $UsnJrnl/$DATA/$Max "12941294+ "attribute (size is 0x%llx but should be at "12951295+ "least 0x%x bytes).", i_size_read(tmp_ino),12961296+ sizeof(USN_HEADER));12971297+ return FALSE;12981298+ }12991299+ /* Get the $DATA/$J attribute. */13001300+ tmp_ino = ntfs_attr_iget(vol->usnjrnl_ino, AT_DATA, J, 2);13011301+ if (IS_ERR(tmp_ino)) {13021302+ ntfs_error(vol->sb, "Failed to load $UsnJrnl/$DATA/$J "13031303+ "attribute.");13041304+ return FALSE;13051305+ }13061306+ vol->usnjrnl_j_ino = tmp_ino;13071307+ /* Verify $J is non-resident and sparse. */13081308+ tmp_ni = NTFS_I(vol->usnjrnl_j_ino);13091309+ if (unlikely(!NInoNonResident(tmp_ni) || !NInoSparse(tmp_ni))) {13101310+ ntfs_error(vol->sb, "$UsnJrnl/$DATA/$J attribute is resident "13111311+ "and/or not sparse.");13121312+ return FALSE;13131313+ }13141314+ /* Read the USN_HEADER from $DATA/$Max. */13151315+ page = ntfs_map_page(vol->usnjrnl_max_ino->i_mapping, 0);13161316+ if (IS_ERR(page)) {13171317+ ntfs_error(vol->sb, "Failed to read from $UsnJrnl/$DATA/$Max "13181318+ "attribute.");13191319+ return FALSE;13201320+ }13211321+ uh = (USN_HEADER*)page_address(page);13221322+ /* Sanity check the $Max. */13231323+ if (unlikely(sle64_to_cpu(uh->allocation_delta) >13241324+ sle64_to_cpu(uh->maximum_size))) {13251325+ ntfs_error(vol->sb, "Allocation delta (0x%llx) exceeds "13261326+ "maximum size (0x%llx). $UsnJrnl is corrupt.",13271327+ (long long)sle64_to_cpu(uh->allocation_delta),13281328+ (long long)sle64_to_cpu(uh->maximum_size));13291329+ ntfs_unmap_page(page);13301330+ return FALSE;13311331+ }13321332+ /*13331333+ * If the transaction log has been stamped and nothing has been written13341334+ * to it since, we do not need to stamp it.13351335+ */13361336+ if (unlikely(sle64_to_cpu(uh->lowest_valid_usn) >=13371337+ i_size_read(vol->usnjrnl_j_ino))) {13381338+ if (likely(sle64_to_cpu(uh->lowest_valid_usn) ==13391339+ i_size_read(vol->usnjrnl_j_ino))) {13401340+ ntfs_unmap_page(page);13411341+ ntfs_debug("$UsnJrnl is enabled but nothing has been "13421342+ "logged since it was last stamped. "13431343+ "Treating this as if the volume does "13441344+ "not have transaction logging "13451345+ "enabled.");13461346+ goto not_enabled;13471347+ }13481348+ ntfs_error(vol->sb, "$UsnJrnl has lowest valid usn (0x%llx) "13491349+ "which is out of bounds (0x%llx). $UsnJrnl "13501350+ "is corrupt.",13511351+ (long long)sle64_to_cpu(uh->lowest_valid_usn),13521352+ i_size_read(vol->usnjrnl_j_ino));13531353+ ntfs_unmap_page(page);13541354+ return FALSE;13551355+ }13561356+ ntfs_unmap_page(page);13571357+ ntfs_debug("Done.");13581358+ return TRUE;13591359+}13601360+13611361+/**13471362 * load_and_init_attrdef - load the attribute definitions table for a volume13481363 * @vol: ntfs super block describing device whose attrdef to load13491364 *···15121205 */15131206static BOOL load_and_init_attrdef(ntfs_volume *vol)15141207{12081208+ loff_t i_size;15151209 struct super_block *sb = vol->sb;15161210 struct inode *ino;15171211 struct page *page;15181518- unsigned long index, max_index;12121212+ pgoff_t index, max_index;15191213 unsigned int size;1520121415211215 ntfs_debug("Entering.");···15271219 iput(ino);15281220 goto failed;15291221 }12221222+ NInoSetSparseDisabled(NTFS_I(ino));15301223 /* The size of FILE_AttrDef must be above 0 and fit inside 31 bits. */15311531- if (!ino->i_size || ino->i_size > 0x7fffffff)12241224+ i_size = i_size_read(ino);12251225+ if (i_size <= 0 || i_size > 0x7fffffff)15321226 goto iput_failed;15331533- vol->attrdef = (ATTR_DEF*)ntfs_malloc_nofs(ino->i_size);12271227+ vol->attrdef = (ATTR_DEF*)ntfs_malloc_nofs(i_size);15341228 if (!vol->attrdef)15351229 goto iput_failed;15361230 index = 0;15371537- max_index = ino->i_size >> PAGE_CACHE_SHIFT;12311231+ max_index = i_size >> PAGE_CACHE_SHIFT;15381232 size = PAGE_CACHE_SIZE;15391233 while (index < max_index) {15401234 /* Read the attrdef table and copy it into the linear buffer. */···15491239 ntfs_unmap_page(page);15501240 };15511241 if (size == PAGE_CACHE_SIZE) {15521552- size = ino->i_size & ~PAGE_CACHE_MASK;12421242+ size = i_size & ~PAGE_CACHE_MASK;15531243 if (size)15541244 goto read_partial_attrdef_page;15551245 }15561556- vol->attrdef_size = ino->i_size;15571557- ntfs_debug("Read %llu bytes from $AttrDef.", ino->i_size);12461246+ vol->attrdef_size = i_size;12471247+ ntfs_debug("Read %llu bytes from $AttrDef.", i_size);15581248 iput(ino);15591249 return TRUE;15601250free_iput_failed:···15771267 */15781268static BOOL load_and_init_upcase(ntfs_volume *vol)15791269{12701270+ loff_t i_size;15801271 struct super_block *sb = vol->sb;15811272 struct inode *ino;15821273 struct page *page;15831583- unsigned long index, max_index;12741274+ pgoff_t index, max_index;15841275 unsigned int size;15851276 int i, max;15861277···15971286 * The upcase size must not be above 64k Unicode characters, must not15981287 * be zero and must be a multiple of sizeof(ntfschar).15991288 */16001600- if (!ino->i_size || ino->i_size & (sizeof(ntfschar) - 1) ||16011601- ino->i_size > 64ULL * 1024 * sizeof(ntfschar))12891289+ i_size = i_size_read(ino);12901290+ if (!i_size || i_size & (sizeof(ntfschar) - 1) ||12911291+ i_size > 64ULL * 1024 * sizeof(ntfschar))16021292 goto iput_upcase_failed;16031603- vol->upcase = (ntfschar*)ntfs_malloc_nofs(ino->i_size);12931293+ vol->upcase = (ntfschar*)ntfs_malloc_nofs(i_size);16041294 if (!vol->upcase)16051295 goto iput_upcase_failed;16061296 index = 0;16071607- max_index = ino->i_size >> PAGE_CACHE_SHIFT;12971297+ max_index = i_size >> PAGE_CACHE_SHIFT;16081298 size = PAGE_CACHE_SIZE;16091299 while (index < max_index) {16101300 /* Read the upcase table and copy it into the linear buffer. */···16181306 ntfs_unmap_page(page);16191307 };16201308 if (size == PAGE_CACHE_SIZE) {16211621- size = ino->i_size & ~PAGE_CACHE_MASK;13091309+ size = i_size & ~PAGE_CACHE_MASK;16221310 if (size)16231311 goto read_partial_upcase_page;16241312 }16251625- vol->upcase_len = ino->i_size >> UCHAR_T_SIZE_BITS;13131313+ vol->upcase_len = i_size >> UCHAR_T_SIZE_BITS;16261314 ntfs_debug("Read %llu bytes from $UpCase (expected %zu bytes).",16271627- ino->i_size, 64 * 1024 * sizeof(ntfschar));13151315+ i_size, 64 * 1024 * sizeof(ntfschar));16281316 iput(ino);16291317 down(&ntfs_lock);16301318 if (!default_upcase) {···16881376 MFT_RECORD *m;16891377 VOLUME_INFORMATION *vi;16901378 ntfs_attr_search_ctx *ctx;13791379+#ifdef NTFS_RW13801380+ int err;13811381+#endif /* NTFS_RW */1691138216921383 ntfs_debug("Entering.");16931384#ifdef NTFS_RW···17501435 iput(vol->lcnbmp_ino);17511436 goto bitmap_failed;17521437 }17531753- if ((vol->nr_clusters + 7) >> 3 > vol->lcnbmp_ino->i_size) {14381438+ NInoSetSparseDisabled(NTFS_I(vol->lcnbmp_ino));14391439+ if ((vol->nr_clusters + 7) >> 3 > i_size_read(vol->lcnbmp_ino)) {17541440 iput(vol->lcnbmp_ino);17551441bitmap_failed:17561442 ntfs_error(sb, "Failed to load $Bitmap.");···18021486 unmap_mft_record(NTFS_I(vol->vol_ino));18031487 printk(KERN_INFO "NTFS volume version %i.%i.\n", vol->major_ver,18041488 vol->minor_ver);14891489+ if (vol->major_ver < 3 && NVolSparseEnabled(vol)) {14901490+ ntfs_warning(vol->sb, "Disabling sparse support due to NTFS "14911491+ "volume version %i.%i (need at least version "14921492+ "3.0).", vol->major_ver, vol->minor_ver);14931493+ NVolClearSparseEnabled(vol);14941494+ }18051495#ifdef NTFS_RW18061496 /* Make sure that no unsupported volume flags are set. */18071497 if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) {···18671545 /* This will prevent a read-write remount. */18681546 NVolSetErrors(vol);18691547 }15481548+#endif /* NTFS_RW */15491549+ /* Get the root directory inode so we can do path lookups. */15501550+ vol->root_ino = ntfs_iget(sb, FILE_root);15511551+ if (IS_ERR(vol->root_ino) || is_bad_inode(vol->root_ino)) {15521552+ if (!IS_ERR(vol->root_ino))15531553+ iput(vol->root_ino);15541554+ ntfs_error(sb, "Failed to load root directory.");15551555+ goto iput_logfile_err_out;15561556+ }15571557+#ifdef NTFS_RW15581558+ /*15591559+ * Check if Windows is suspended to disk on the target volume. If it15601560+ * is hibernated, we must not write *anything* to the disk so set15611561+ * NVolErrors() without setting the dirty volume flag and mount15621562+ * read-only. This will prevent read-write remounting and it will also15631563+ * prevent all writes.15641564+ */15651565+ err = check_windows_hibernation_status(vol);15661566+ if (unlikely(err)) {15671567+ static const char *es1a = "Failed to determine if Windows is "15681568+ "hibernated";15691569+ static const char *es1b = "Windows is hibernated";15701570+ static const char *es2 = ". Run chkdsk.";15711571+ const char *es1;15721572+15731573+ es1 = err < 0 ? es1a : es1b;15741574+ /* If a read-write mount, convert it to a read-only mount. */15751575+ if (!(sb->s_flags & MS_RDONLY)) {15761576+ if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO |15771577+ ON_ERRORS_CONTINUE))) {15781578+ ntfs_error(sb, "%s and neither on_errors="15791579+ "continue nor on_errors="15801580+ "remount-ro was specified%s",15811581+ es1, es2);15821582+ goto iput_root_err_out;15831583+ }15841584+ sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;15851585+ ntfs_error(sb, "%s. Mounting read-only%s", es1, es2);15861586+ } else15871587+ ntfs_warning(sb, "%s. Will not be able to remount "15881588+ "read-write%s", es1, es2);15891589+ /* This will prevent a read-write remount. */15901590+ NVolSetErrors(vol);15911591+ }18701592 /* If (still) a read-write mount, mark the volume dirty. */18711593 if (!(sb->s_flags & MS_RDONLY) &&18721594 ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY)) {···19241558 ntfs_error(sb, "%s and neither on_errors=continue nor "19251559 "on_errors=remount-ro was specified%s",19261560 es1, es2);19271927- goto iput_logfile_err_out;15611561+ goto iput_root_err_out;19281562 }19291563 ntfs_error(sb, "%s. Mounting read-only%s", es1, es2);19301564 sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;···19511585 ntfs_error(sb, "%s and neither on_errors=continue nor "19521586 "on_errors=remount-ro was specified%s",19531587 es1, es2);19541954- goto iput_logfile_err_out;15881588+ goto iput_root_err_out;19551589 }19561590 ntfs_error(sb, "%s. Mounting read-only%s", es1, es2);19571591 sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;···19701604 ntfs_error(sb, "%s and neither on_errors=continue nor "19711605 "on_errors=remount-ro was specified%s",19721606 es1, es2);19731973- goto iput_logfile_err_out;16071607+ goto iput_root_err_out;19741608 }19751609 ntfs_error(sb, "%s. Mounting read-only%s", es1, es2);19761610 sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;19771611 NVolSetErrors(vol);19781612 }19791613#endif /* NTFS_RW */19801980- /* Get the root directory inode. */19811981- vol->root_ino = ntfs_iget(sb, FILE_root);19821982- if (IS_ERR(vol->root_ino) || is_bad_inode(vol->root_ino)) {19831983- if (!IS_ERR(vol->root_ino))19841984- iput(vol->root_ino);19851985- ntfs_error(sb, "Failed to load root directory.");19861986- goto iput_logfile_err_out;19871987- }19881614 /* If on NTFS versions before 3.0, we are done. */19891989- if (vol->major_ver < 3)16151615+ if (unlikely(vol->major_ver < 3))19901616 return TRUE;19911617 /* NTFS 3.0+ specific initialization. */19921618 /* Get the security descriptors inode. */···19891631 ntfs_error(sb, "Failed to load $Secure.");19901632 goto iput_root_err_out;19911633 }19921992- // FIXME: Initialize security.16341634+ // TODO: Initialize security.19931635 /* Get the extended system files' directory inode. */19941636 vol->extend_ino = ntfs_iget(sb, FILE_Extend);19951637 if (IS_ERR(vol->extend_ino) || is_bad_inode(vol->extend_ino)) {···20401682 sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;20411683 NVolSetErrors(vol);20421684 }20432043- // TODO: Delete or checkpoint the $UsnJrnl if it exists.16851685+ /*16861686+ * Find the transaction log file ($UsnJrnl), load it if present, check16871687+ * it, and set it up.16881688+ */16891689+ if (!load_and_init_usnjrnl(vol)) {16901690+ static const char *es1 = "Failed to load $UsnJrnl";16911691+ static const char *es2 = ". Run chkdsk.";16921692+16931693+ /* If a read-write mount, convert it to a read-only mount. */16941694+ if (!(sb->s_flags & MS_RDONLY)) {16951695+ if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO |16961696+ ON_ERRORS_CONTINUE))) {16971697+ ntfs_error(sb, "%s and neither on_errors="16981698+ "continue nor on_errors="16991699+ "remount-ro was specified%s",17001700+ es1, es2);17011701+ goto iput_usnjrnl_err_out;17021702+ }17031703+ sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;17041704+ ntfs_error(sb, "%s. Mounting read-only%s", es1, es2);17051705+ } else17061706+ ntfs_warning(sb, "%s. Will not be able to remount "17071707+ "read-write%s", es1, es2);17081708+ /* This will prevent a read-write remount. */17091709+ NVolSetErrors(vol);17101710+ }17111711+ /* If (still) a read-write mount, stamp the transaction log. */17121712+ if (!(sb->s_flags & MS_RDONLY) && !ntfs_stamp_usnjrnl(vol)) {17131713+ static const char *es1 = "Failed to stamp transaction log "17141714+ "($UsnJrnl)";17151715+ static const char *es2 = ". Run chkdsk.";17161716+17171717+ /* Convert to a read-only mount. */17181718+ if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO |17191719+ ON_ERRORS_CONTINUE))) {17201720+ ntfs_error(sb, "%s and neither on_errors=continue nor "17211721+ "on_errors=remount-ro was specified%s",17221722+ es1, es2);17231723+ goto iput_usnjrnl_err_out;17241724+ }17251725+ ntfs_error(sb, "%s. Mounting read-only%s", es1, es2);17261726+ sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME;17271727+ NVolSetErrors(vol);17281728+ }20441729#endif /* NTFS_RW */20451730 return TRUE;20461731#ifdef NTFS_RW17321732+iput_usnjrnl_err_out:17331733+ if (vol->usnjrnl_j_ino)17341734+ iput(vol->usnjrnl_j_ino);17351735+ if (vol->usnjrnl_max_ino)17361736+ iput(vol->usnjrnl_max_ino);17371737+ if (vol->usnjrnl_ino)17381738+ iput(vol->usnjrnl_ino);20471739iput_quota_err_out:20481740 if (vol->quota_q_ino)20491741 iput(vol->quota_q_ino);···2167175921681760 /* NTFS 3.0+ specific. */21691761 if (vol->major_ver >= 3) {17621762+ if (vol->usnjrnl_j_ino)17631763+ ntfs_commit_inode(vol->usnjrnl_j_ino);17641764+ if (vol->usnjrnl_max_ino)17651765+ ntfs_commit_inode(vol->usnjrnl_max_ino);17661766+ if (vol->usnjrnl_ino)17671767+ ntfs_commit_inode(vol->usnjrnl_ino);21701768 if (vol->quota_q_ino)21711769 ntfs_commit_inode(vol->quota_q_ino);21721770 if (vol->quota_ino)···22281814 /* NTFS 3.0+ specific clean up. */22291815 if (vol->major_ver >= 3) {22301816#ifdef NTFS_RW18171817+ if (vol->usnjrnl_j_ino) {18181818+ iput(vol->usnjrnl_j_ino);18191819+ vol->usnjrnl_j_ino = NULL;18201820+ }18211821+ if (vol->usnjrnl_max_ino) {18221822+ iput(vol->usnjrnl_max_ino);18231823+ vol->usnjrnl_max_ino = NULL;18241824+ }18251825+ if (vol->usnjrnl_ino) {18261826+ iput(vol->usnjrnl_ino);18271827+ vol->usnjrnl_ino = NULL;18281828+ }22311829 if (vol->quota_q_ino) {22321830 iput(vol->quota_q_ino);22331831 vol->quota_q_ino = NULL;···23851959 struct address_space *mapping = vol->lcnbmp_ino->i_mapping;23861960 filler_t *readpage = (filler_t*)mapping->a_ops->readpage;23871961 struct page *page;23882388- unsigned long index, max_index;23892389- unsigned int max_size;19621962+ pgoff_t index, max_index;2390196323911964 ntfs_debug("Entering.");23921965 /* Serialize accesses to the cluster bitmap. */···23971972 */23981973 max_index = (((vol->nr_clusters + 7) >> 3) + PAGE_CACHE_SIZE - 1) >>23991974 PAGE_CACHE_SHIFT;24002400- /* Use multiples of 4 bytes. */24012401- max_size = PAGE_CACHE_SIZE >> 2;24022402- ntfs_debug("Reading $Bitmap, max_index = 0x%lx, max_size = 0x%x.",24032403- max_index, max_size);24042404- for (index = 0UL; index < max_index; index++) {19751975+ /* Use multiples of 4 bytes, thus max_size is PAGE_CACHE_SIZE / 4. */19761976+ ntfs_debug("Reading $Bitmap, max_index = 0x%lx, max_size = 0x%lx.",19771977+ max_index, PAGE_CACHE_SIZE / 4);19781978+ for (index = 0; index < max_index; index++) {24051979 unsigned int i;24061980 /*24071981 * Read the page from page cache, getting it from backing store···24322008 * the result as all out of range bytes are set to zero by24332009 * ntfs_readpage().24342010 */24352435- for (i = 0; i < max_size; i++)20112011+ for (i = 0; i < PAGE_CACHE_SIZE / 4; i++)24362012 nr_free -= (s64)hweight32(kaddr[i]);24372013 kunmap_atomic(kaddr, KM_USER0);24382014 page_cache_release(page);···24552031/**24562032 * __get_nr_free_mft_records - return the number of free inodes on a volume24572033 * @vol: ntfs volume for which to obtain free inode count20342034+ * @nr_free: number of mft records in filesystem20352035+ * @max_index: maximum number of pages containing set bits24582036 *24592037 * Calculate the number of free mft records (inodes) on the mounted NTFS24602038 * volume @vol. We actually calculate the number of mft records in use instead···24692043 *24702044 * NOTE: Caller must hold mftbmp_lock rw_semaphore for reading or writing.24712045 */24722472-static unsigned long __get_nr_free_mft_records(ntfs_volume *vol)20462046+static unsigned long __get_nr_free_mft_records(ntfs_volume *vol,20472047+ s64 nr_free, const pgoff_t max_index)24732048{24742474- s64 nr_free;24752049 u32 *kaddr;24762050 struct address_space *mapping = vol->mftbmp_ino->i_mapping;24772051 filler_t *readpage = (filler_t*)mapping->a_ops->readpage;24782052 struct page *page;24792479- unsigned long index, max_index;24802480- unsigned int max_size;20532053+ pgoff_t index;2481205424822055 ntfs_debug("Entering.");24832483- /* Number of mft records in file system (at this point in time). */24842484- nr_free = vol->mft_ino->i_size >> vol->mft_record_size_bits;24852485- /*24862486- * Convert the maximum number of set bits into bytes rounded up, then24872487- * convert into multiples of PAGE_CACHE_SIZE, rounding up so that if we24882488- * have one full and one partial page max_index = 2.24892489- */24902490- max_index = ((((NTFS_I(vol->mft_ino)->initialized_size >>24912491- vol->mft_record_size_bits) + 7) >> 3) +24922492- PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;24932493- /* Use multiples of 4 bytes. */24942494- max_size = PAGE_CACHE_SIZE >> 2;20562056+ /* Use multiples of 4 bytes, thus max_size is PAGE_CACHE_SIZE / 4. */24952057 ntfs_debug("Reading $MFT/$BITMAP, max_index = 0x%lx, max_size = "24962496- "0x%x.", max_index, max_size);24972497- for (index = 0UL; index < max_index; index++) {20582058+ "0x%lx.", max_index, PAGE_CACHE_SIZE / 4);20592059+ for (index = 0; index < max_index; index++) {24982060 unsigned int i;24992061 /*25002062 * Read the page from page cache, getting it from backing store···25142100 * the result as all out of range bytes are set to zero by25152101 * ntfs_readpage().25162102 */25172517- for (i = 0; i < max_size; i++)21032103+ for (i = 0; i < PAGE_CACHE_SIZE / 4; i++)25182104 nr_free -= (s64)hweight32(kaddr[i]);25192105 kunmap_atomic(kaddr, KM_USER0);25202106 page_cache_release(page);···25482134 */25492135static int ntfs_statfs(struct super_block *sb, struct kstatfs *sfs)25502136{25512551- ntfs_volume *vol = NTFS_SB(sb);25522137 s64 size;21382138+ ntfs_volume *vol = NTFS_SB(sb);21392139+ ntfs_inode *mft_ni = NTFS_I(vol->mft_ino);21402140+ pgoff_t max_index;21412141+ unsigned long flags;2553214225542143 ntfs_debug("Entering.");25552144 /* Type of filesystem. */···25602143 /* Optimal transfer block size. */25612144 sfs->f_bsize = PAGE_CACHE_SIZE;25622145 /*25632563- * Total data blocks in file system in units of f_bsize and since21462146+ * Total data blocks in filesystem in units of f_bsize and since25642147 * inodes are also stored in data blocs ($MFT is a file) this is just25652148 * the total clusters.25662149 */25672150 sfs->f_blocks = vol->nr_clusters << vol->cluster_size_bits >>25682151 PAGE_CACHE_SHIFT;25692569- /* Free data blocks in file system in units of f_bsize. */21522152+ /* Free data blocks in filesystem in units of f_bsize. */25702153 size = get_nr_free_clusters(vol) << vol->cluster_size_bits >>25712154 PAGE_CACHE_SHIFT;25722155 if (size < 0LL)···25752158 sfs->f_bavail = sfs->f_bfree = size;25762159 /* Serialize accesses to the inode bitmap. */25772160 down_read(&vol->mftbmp_lock);25782578- /* Number of inodes in file system (at this point in time). */25792579- sfs->f_files = vol->mft_ino->i_size >> vol->mft_record_size_bits;21612161+ read_lock_irqsave(&mft_ni->size_lock, flags);21622162+ size = i_size_read(vol->mft_ino) >> vol->mft_record_size_bits;21632163+ /*21642164+ * Convert the maximum number of set bits into bytes rounded up, then21652165+ * convert into multiples of PAGE_CACHE_SIZE, rounding up so that if we21662166+ * have one full and one partial page max_index = 2.21672167+ */21682168+ max_index = ((((mft_ni->initialized_size >> vol->mft_record_size_bits)21692169+ + 7) >> 3) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;21702170+ read_unlock_irqrestore(&mft_ni->size_lock, flags);21712171+ /* Number of inodes in filesystem (at this point in time). */21722172+ sfs->f_files = size;25802173 /* Free inodes in fs (based on current total count). */25812581- sfs->f_ffree = __get_nr_free_mft_records(vol);21742174+ sfs->f_ffree = __get_nr_free_mft_records(vol, size, max_index);25822175 up_read(&vol->mftbmp_lock);25832176 /*25842177 * File system id. This is extremely *nix flavour dependent and even25852178 * within Linux itself all fs do their own thing. I interpret this to25862179 * mean a unique id associated with the mounted fs and not the id25872587- * associated with the file system driver, the latter is already given25882588- * by the file system type in sfs->f_type. Thus we use the 64-bit21802180+ * associated with the filesystem driver, the latter is already given21812181+ * by the filesystem type in sfs->f_type. Thus we use the 64-bit25892182 * volume serial number splitting it into two 32-bit parts. We enter25902183 * the least significant 32-bits in f_fsid[0] and the most significant25912184 * 32-bits in f_fsid[1].···26462219 proc. */26472220};2648222126492649-26502222/**26512651- * Declarations for NTFS specific export operations (fs/ntfs/namei.c).26522652- */26532653-extern struct dentry *ntfs_get_parent(struct dentry *child_dent);26542654-extern struct dentry *ntfs_get_dentry(struct super_block *sb, void *fh);26552655-26562656-/**26572657- * Export operations allowing NFS exporting of mounted NTFS partitions.26582658- *26592659- * We use the default ->decode_fh() and ->encode_fh() for now. Note that they26602660- * use 32 bits to store the inode number which is an unsigned long so on 64-bit26612661- * architectures is usually 64 bits so it would all fail horribly on huge26622662- * volumes. I guess we need to define our own encode and decode fh functions26632663- * that store 64-bit inode numbers at some point but for now we will ignore the26642664- * problem...26652665- *26662666- * We also use the default ->get_name() helper (used by ->decode_fh() via26672667- * fs/exportfs/expfs.c::find_exported_dentry()) as that is completely fs26682668- * independent.26692669- *26702670- * The default ->get_parent() just returns -EACCES so we have to provide our26712671- * own and the default ->get_dentry() is incompatible with NTFS due to not26722672- * allowing the inode number 0 which is used in NTFS for the system file $MFT26732673- * and due to using iget() whereas NTFS needs ntfs_iget().26742674- */26752675-static struct export_operations ntfs_export_ops = {26762676- .get_parent = ntfs_get_parent, /* Find the parent of a given26772677- directory. */26782678- .get_dentry = ntfs_get_dentry, /* Find a dentry for the inode26792679- given a file handle26802680- sub-fragment. */26812681-};26822682-26832683-/**26842684- * ntfs_fill_super - mount an ntfs files system26852685- * @sb: super block of ntfs file system to mount22232223+ * ntfs_fill_super - mount an ntfs filesystem22242224+ * @sb: super block of ntfs filesystem to mount26862225 * @opt: string containing the mount options26872226 * @silent: silence error output26882227 *26892228 * ntfs_fill_super() is called by the VFS to mount the device described by @sb26902690- * with the mount otions in @data with the NTFS file system.22292229+ * with the mount otions in @data with the NTFS filesystem.26912230 *26922231 * If @silent is true, remain silent even if errors are detected. This is used26932693- * during bootup, when the kernel tries to mount the root file system with all26942694- * registered file systems one after the other until one succeeds. This implies26952695- * that all file systems except the correct one will quite correctly and22322232+ * during bootup, when the kernel tries to mount the root filesystem with all22332233+ * registered filesystems one after the other until one succeeds. This implies22342234+ * that all filesystems except the correct one will quite correctly and26962235 * expectedly return an error, but nobody wants to see error messages when in26972236 * fact this is what is supposed to happen.26982237 *···26852292 return -ENOMEM;26862293 }26872294 /* Initialize ntfs_volume structure. */26882688- memset(vol, 0, sizeof(ntfs_volume));26892689- vol->sb = sb;26902690- vol->upcase = NULL;26912691- vol->attrdef = NULL;26922692- vol->mft_ino = NULL;26932693- vol->mftbmp_ino = NULL;22952295+ *vol = (ntfs_volume) {22962296+ .sb = sb,22972297+ /*22982298+ * Default is group and other don't have any access to files or22992299+ * directories while owner has full access. Further, files by23002300+ * default are not executable but directories are of course23012301+ * browseable.23022302+ */23032303+ .fmask = 0177,23042304+ .dmask = 0077,23052305+ };26942306 init_rwsem(&vol->mftbmp_lock);26952695-#ifdef NTFS_RW26962696- vol->mftmirr_ino = NULL;26972697- vol->logfile_ino = NULL;26982698-#endif /* NTFS_RW */26992699- vol->lcnbmp_ino = NULL;27002307 init_rwsem(&vol->lcnbmp_lock);27012701- vol->vol_ino = NULL;27022702- vol->root_ino = NULL;27032703- vol->secure_ino = NULL;27042704- vol->extend_ino = NULL;27052705-#ifdef NTFS_RW27062706- vol->quota_ino = NULL;27072707- vol->quota_q_ino = NULL;27082708-#endif /* NTFS_RW */27092709- vol->nls_map = NULL;27102710-27112711- /*27122712- * Default is group and other don't have any access to files or27132713- * directories while owner has full access. Further, files by default27142714- * are not executable but directories are of course browseable.27152715- */27162716- vol->fmask = 0177;27172717- vol->dmask = 0077;2718230827192309 unlock_kernel();23102310+23112311+ /* By default, enable sparse support. */23122312+ NVolSetSparseEnabled(vol);2720231327212314 /* Important to get the mount options dealt with now. */27222315 if (!parse_options(vol, (char*)opt))···27262347 }2727234827282349 /* Get the size of the device in units of NTFS_BLOCK_SIZE bytes. */27292729- vol->nr_blocks = sb->s_bdev->bd_inode->i_size >> NTFS_BLOCK_SIZE_BITS;23502350+ vol->nr_blocks = i_size_read(sb->s_bdev->bd_inode) >>23512351+ NTFS_BLOCK_SIZE_BITS;2730235227312353 /* Read the boot sector and return unlocked buffer head to it. */27322354 if (!(bh = read_ntfs_boot_sector(sb, silent))) {···28562476 /* NTFS 3.0+ specific clean up. */28572477 if (vol->major_ver >= 3) {28582478#ifdef NTFS_RW24792479+ if (vol->usnjrnl_j_ino) {24802480+ iput(vol->usnjrnl_j_ino);24812481+ vol->usnjrnl_j_ino = NULL;24822482+ }24832483+ if (vol->usnjrnl_max_ino) {24842484+ iput(vol->usnjrnl_max_ino);24852485+ vol->usnjrnl_max_ino = NULL;24862486+ }24872487+ if (vol->usnjrnl_ino) {24882488+ iput(vol->usnjrnl_ino);24892489+ vol->usnjrnl_ino = NULL;24902490+ }28592491 if (vol->quota_q_ino) {28602492 iput(vol->quota_q_ino);28612493 vol->quota_q_ino = NULL;···29732581 */29742582kmem_cache_t *ntfs_name_cache;2975258329762976-/* Slab caches for efficient allocation/deallocation of of inodes. */25842584+/* Slab caches for efficient allocation/deallocation of inodes. */29772585kmem_cache_t *ntfs_inode_cache;29782586kmem_cache_t *ntfs_big_inode_cache;29792587···30972705 ntfs_debug("NTFS driver registered successfully.");30982706 return 0; /* Success! */30992707 }31003100- printk(KERN_CRIT "NTFS: Failed to register NTFS file system driver!\n");27082708+ printk(KERN_CRIT "NTFS: Failed to register NTFS filesystem driver!\n");3101270931022710sysctl_err_out:31032711 kmem_cache_destroy(ntfs_big_inode_cache);···31112719 kmem_cache_destroy(ntfs_index_ctx_cache);31122720ictx_err_out:31132721 if (!err) {31143114- printk(KERN_CRIT "NTFS: Aborting NTFS file system driver "27222722+ printk(KERN_CRIT "NTFS: Aborting NTFS filesystem driver "31152723 "registration...\n");31162724 err = -ENOMEM;31172725 }···31512759}3152276031532761MODULE_AUTHOR("Anton Altaparmakov <aia21@cantab.net>");31543154-MODULE_DESCRIPTION("NTFS 1.2/3.x driver - Copyright (c) 2001-2004 Anton Altaparmakov");27622762+MODULE_DESCRIPTION("NTFS 1.2/3.x driver - Copyright (c) 2001-2005 Anton Altaparmakov");31552763MODULE_VERSION(NTFS_VERSION);31562764MODULE_LICENSE("GPL");31572765#ifdef DEBUG
+2-2
fs/ntfs/sysctl.c
···33 * the Linux-NTFS project. Adapted from the old NTFS driver,44 * Copyright (C) 1997 Martin von L�wis, R�gis Duchesne55 *66- * Copyright (c) 2002-2004 Anton Altaparmakov66+ * Copyright (c) 2002-2005 Anton Altaparmakov77 *88 * This program/include file is free software; you can redistribute it and/or99 * modify it under the terms of the GNU General Public License as published···6767 return -ENOMEM;6868#ifdef CONFIG_PROC_FS6969 /*7070- * If the proc file system is in use and we are a module, need7070+ * If the proc filesystem is in use and we are a module, need7171 * to set the owner of our proc entry to our module. In the7272 * non-modular case, THIS_MODULE is NULL, so this is ok.7373 */
+2-2
fs/ntfs/time.h
···11/*22 * time.h - NTFS time conversion functions. Part of the Linux-NTFS project.33 *44- * Copyright (c) 2001-2004 Anton Altaparmakov44+ * Copyright (c) 2001-2005 Anton Altaparmakov55 *66 * This program/include file is free software; you can redistribute it and/or77 * modify it under the terms of the GNU General Public License as published···8787 struct timespec ts;88888989 /* Subtract the NTFS time offset. */9090- s64 t = sle64_to_cpu(time) - NTFS_TIME_OFFSET;9090+ u64 t = (u64)(sle64_to_cpu(time) - NTFS_TIME_OFFSET);9191 /*9292 * Convert the time to 1-second intervals and the remainder to9393 * 1-nano-second intervals.
+9-1
fs/ntfs/types.h
···22 * types.h - Defines for NTFS Linux kernel driver specific types.33 * Part of the Linux-NTFS project.44 *55- * Copyright (c) 2001-2004 Anton Altaparmakov55+ * Copyright (c) 2001-2005 Anton Altaparmakov66 *77 * This program/include file is free software; you can redistribute it and/or88 * modify it under the terms of the GNU General Public License as published···5252 */5353typedef s64 LSN;5454typedef sle64 leLSN;5555+5656+/*5757+ * The NTFS transaction log $UsnJrnl uses usn which are signed 64-bit values.5858+ * We define our own type USN, to allow for type checking and better code5959+ * readability.6060+ */6161+typedef s64 USN;6262+typedef sle64 leUSN;55635664typedef enum {5765 FALSE = 0,
+1-1
fs/ntfs/unistr.c
···264264265265 /* We don't trust outside sources. */266266 if (ins) {267267- ucs = (ntfschar*)kmem_cache_alloc(ntfs_name_cache, SLAB_NOFS);267267+ ucs = kmem_cache_alloc(ntfs_name_cache, SLAB_NOFS);268268 if (ucs) {269269 for (i = o = 0; i < ins_len; i += wc_len) {270270 wc_len = nls->char2uni(ins + i, ins_len - i,
+84
fs/ntfs/usnjrnl.c
···11+/*22+ * usnjrnl.h - NTFS kernel transaction log ($UsnJrnl) handling. Part of the33+ * Linux-NTFS project.44+ *55+ * Copyright (c) 2005 Anton Altaparmakov66+ *77+ * This program/include file is free software; you can redistribute it and/or88+ * modify it under the terms of the GNU General Public License as published99+ * by the Free Software Foundation; either version 2 of the License, or1010+ * (at your option) any later version.1111+ *1212+ * This program/include file is distributed in the hope that it will be1313+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty1414+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1515+ * GNU General Public License for more details.1616+ *1717+ * You should have received a copy of the GNU General Public License1818+ * along with this program (in the main directory of the Linux-NTFS1919+ * distribution in the file COPYING); if not, write to the Free Software2020+ * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA2121+ */2222+2323+#ifdef NTFS_RW2424+2525+#include <linux/fs.h>2626+#include <linux/highmem.h>2727+#include <linux/mm.h>2828+2929+#include "aops.h"3030+#include "debug.h"3131+#include "endian.h"3232+#include "time.h"3333+#include "types.h"3434+#include "usnjrnl.h"3535+#include "volume.h"3636+3737+/**3838+ * ntfs_stamp_usnjrnl - stamp the transaction log ($UsnJrnl) on an ntfs volume3939+ * @vol: ntfs volume on which to stamp the transaction log4040+ *4141+ * Stamp the transaction log ($UsnJrnl) on the ntfs volume @vol and return4242+ * TRUE on success and FALSE on error.4343+ *4444+ * This function assumes that the transaction log has already been loaded and4545+ * consistency checked by a call to fs/ntfs/super.c::load_and_init_usnjrnl().4646+ */4747+BOOL ntfs_stamp_usnjrnl(ntfs_volume *vol)4848+{4949+ ntfs_debug("Entering.");5050+ if (likely(!NVolUsnJrnlStamped(vol))) {5151+ sle64 stamp;5252+ struct page *page;5353+ USN_HEADER *uh;5454+5555+ page = ntfs_map_page(vol->usnjrnl_max_ino->i_mapping, 0);5656+ if (IS_ERR(page)) {5757+ ntfs_error(vol->sb, "Failed to read from "5858+ "$UsnJrnl/$DATA/$Max attribute.");5959+ return FALSE;6060+ }6161+ uh = (USN_HEADER*)page_address(page);6262+ stamp = get_current_ntfs_time();6363+ ntfs_debug("Stamping transaction log ($UsnJrnl): old "6464+ "journal_id 0x%llx, old lowest_valid_usn "6565+ "0x%llx, new journal_id 0x%llx, new "6666+ "lowest_valid_usn 0x%llx.",6767+ (long long)sle64_to_cpu(uh->journal_id),6868+ (long long)sle64_to_cpu(uh->lowest_valid_usn),6969+ (long long)sle64_to_cpu(stamp),7070+ i_size_read(vol->usnjrnl_j_ino));7171+ uh->lowest_valid_usn =7272+ cpu_to_sle64(i_size_read(vol->usnjrnl_j_ino));7373+ uh->journal_id = stamp;7474+ flush_dcache_page(page);7575+ set_page_dirty(page);7676+ ntfs_unmap_page(page);7777+ /* Set the flag so we do not have to do it again on remount. */7878+ NVolSetUsnJrnlStamped(vol);7979+ }8080+ ntfs_debug("Done.");8181+ return TRUE;8282+}8383+8484+#endif /* NTFS_RW */
+205
fs/ntfs/usnjrnl.h
···11+/*22+ * usnjrnl.h - Defines for NTFS kernel transaction log ($UsnJrnl) handling.33+ * Part of the Linux-NTFS project.44+ *55+ * Copyright (c) 2005 Anton Altaparmakov66+ *77+ * This program/include file is free software; you can redistribute it and/or88+ * modify it under the terms of the GNU General Public License as published99+ * by the Free Software Foundation; either version 2 of the License, or1010+ * (at your option) any later version.1111+ *1212+ * This program/include file is distributed in the hope that it will be1313+ * useful, but WITHOUT ANY WARRANTY; without even the implied warranty1414+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1515+ * GNU General Public License for more details.1616+ *1717+ * You should have received a copy of the GNU General Public License1818+ * along with this program (in the main directory of the Linux-NTFS1919+ * distribution in the file COPYING); if not, write to the Free Software2020+ * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA2121+ */2222+2323+#ifndef _LINUX_NTFS_USNJRNL_H2424+#define _LINUX_NTFS_USNJRNL_H2525+2626+#ifdef NTFS_RW2727+2828+#include "types.h"2929+#include "endian.h"3030+#include "layout.h"3131+#include "volume.h"3232+3333+/*3434+ * Transaction log ($UsnJrnl) organization:3535+ *3636+ * The transaction log records whenever a file is modified in any way. So for3737+ * example it will record that file "blah" was written to at a particular time3838+ * but not what was written. If will record that a file was deleted or3939+ * created, that a file was truncated, etc. See below for all the reason4040+ * codes used.4141+ *4242+ * The transaction log is in the $Extend directory which is in the root4343+ * directory of each volume. If it is not present it means transaction4444+ * logging is disabled. If it is present it means transaction logging is4545+ * either enabled or in the process of being disabled in which case we can4646+ * ignore it as it will go away as soon as Windows gets its hands on it.4747+ *4848+ * To determine whether the transaction logging is enabled or in the process4949+ * of being disabled, need to check the volume flags in the5050+ * $VOLUME_INFORMATION attribute in the $Volume system file (which is present5151+ * in the root directory and has a fixed mft record number, see layout.h).5252+ * If the flag VOLUME_DELETE_USN_UNDERWAY is set it means the transaction log5353+ * is in the process of being disabled and if this flag is clear it means the5454+ * transaction log is enabled.5555+ *5656+ * The transaction log consists of two parts; the $DATA/$Max attribute as well5757+ * as the $DATA/$J attribute. $Max is a header describing the transaction5858+ * log whilst $J is the transaction log data itself as a sequence of variable5959+ * sized USN_RECORDs (see below for all the structures).6060+ *6161+ * We do not care about transaction logging at this point in time but we still6262+ * need to let windows know that the transaction log is out of date. To do6363+ * this we need to stamp the transaction log. This involves setting the6464+ * lowest_valid_usn field in the $DATA/$Max attribute to the usn to be used6565+ * for the next added USN_RECORD to the $DATA/$J attribute as well as6666+ * generating a new journal_id in $DATA/$Max.6767+ *6868+ * The journal_id is as of the current version (2.0) of the transaction log6969+ * simply the 64-bit timestamp of when the journal was either created or last7070+ * stamped.7171+ *7272+ * To determine the next usn there are two ways. The first is to parse7373+ * $DATA/$J and to find the last USN_RECORD in it and to add its record_length7474+ * to its usn (which is the byte offset in the $DATA/$J attribute). The7575+ * second is simply to take the data size of the attribute. Since the usns7676+ * are simply byte offsets into $DATA/$J, this is exactly the next usn. For7777+ * obvious reasons we use the second method as it is much simpler and faster.7878+ *7979+ * As an aside, note that to actually disable the transaction log, one would8080+ * need to set the VOLUME_DELETE_USN_UNDERWAY flag (see above), then go8181+ * through all the mft records on the volume and set the usn field in their8282+ * $STANDARD_INFORMATION attribute to zero. Once that is done, one would need8383+ * to delete the transaction log file, i.e. \$Extent\$UsnJrnl, and finally,8484+ * one would need to clear the VOLUME_DELETE_USN_UNDERWAY flag.8585+ *8686+ * Note that if a volume is unmounted whilst the transaction log is being8787+ * disabled, the process will continue the next time the volume is mounted.8888+ * This is why we can safely mount read-write when we see a transaction log8989+ * in the process of being deleted.9090+ */9191+9292+/* Some $UsnJrnl related constants. */9393+#define UsnJrnlMajorVer 29494+#define UsnJrnlMinorVer 09595+9696+/*9797+ * $DATA/$Max attribute. This is (always?) resident and has a fixed size of9898+ * 32 bytes. It contains the header describing the transaction log.9999+ */100100+typedef struct {101101+/*Ofs*/102102+/* 0*/sle64 maximum_size; /* The maximum on-disk size of the $DATA/$J103103+ attribute. */104104+/* 8*/sle64 allocation_delta; /* Number of bytes by which to increase the105105+ size of the $DATA/$J attribute. */106106+/*0x10*/sle64 journal_id; /* Current id of the transaction log. */107107+/*0x18*/leUSN lowest_valid_usn; /* Lowest valid usn in $DATA/$J for the108108+ current journal_id. */109109+/* sizeof() = 32 (0x20) bytes */110110+} __attribute__ ((__packed__)) USN_HEADER;111111+112112+/*113113+ * Reason flags (32-bit). Cumulative flags describing the change(s) to the114114+ * file since it was last opened. I think the names speak for themselves but115115+ * if you disagree check out the descriptions in the Linux NTFS project NTFS116116+ * documentation: http://linux-ntfs.sourceforge.net/ntfs/files/usnjrnl.html117117+ */118118+enum {119119+ USN_REASON_DATA_OVERWRITE = const_cpu_to_le32(0x00000001),120120+ USN_REASON_DATA_EXTEND = const_cpu_to_le32(0x00000002),121121+ USN_REASON_DATA_TRUNCATION = const_cpu_to_le32(0x00000004),122122+ USN_REASON_NAMED_DATA_OVERWRITE = const_cpu_to_le32(0x00000010),123123+ USN_REASON_NAMED_DATA_EXTEND = const_cpu_to_le32(0x00000020),124124+ USN_REASON_NAMED_DATA_TRUNCATION= const_cpu_to_le32(0x00000040),125125+ USN_REASON_FILE_CREATE = const_cpu_to_le32(0x00000100),126126+ USN_REASON_FILE_DELETE = const_cpu_to_le32(0x00000200),127127+ USN_REASON_EA_CHANGE = const_cpu_to_le32(0x00000400),128128+ USN_REASON_SECURITY_CHANGE = const_cpu_to_le32(0x00000800),129129+ USN_REASON_RENAME_OLD_NAME = const_cpu_to_le32(0x00001000),130130+ USN_REASON_RENAME_NEW_NAME = const_cpu_to_le32(0x00002000),131131+ USN_REASON_INDEXABLE_CHANGE = const_cpu_to_le32(0x00004000),132132+ USN_REASON_BASIC_INFO_CHANGE = const_cpu_to_le32(0x00008000),133133+ USN_REASON_HARD_LINK_CHANGE = const_cpu_to_le32(0x00010000),134134+ USN_REASON_COMPRESSION_CHANGE = const_cpu_to_le32(0x00020000),135135+ USN_REASON_ENCRYPTION_CHANGE = const_cpu_to_le32(0x00040000),136136+ USN_REASON_OBJECT_ID_CHANGE = const_cpu_to_le32(0x00080000),137137+ USN_REASON_REPARSE_POINT_CHANGE = const_cpu_to_le32(0x00100000),138138+ USN_REASON_STREAM_CHANGE = const_cpu_to_le32(0x00200000),139139+ USN_REASON_CLOSE = const_cpu_to_le32(0x80000000),140140+};141141+142142+typedef le32 USN_REASON_FLAGS;143143+144144+/*145145+ * Source info flags (32-bit). Information about the source of the change(s)146146+ * to the file. For detailed descriptions of what these mean, see the Linux147147+ * NTFS project NTFS documentation:148148+ * http://linux-ntfs.sourceforge.net/ntfs/files/usnjrnl.html149149+ */150150+enum {151151+ USN_SOURCE_DATA_MANAGEMENT = const_cpu_to_le32(0x00000001),152152+ USN_SOURCE_AUXILIARY_DATA = const_cpu_to_le32(0x00000002),153153+ USN_SOURCE_REPLICATION_MANAGEMENT = const_cpu_to_le32(0x00000004),154154+};155155+156156+typedef le32 USN_SOURCE_INFO_FLAGS;157157+158158+/*159159+ * $DATA/$J attribute. This is always non-resident, is marked as sparse, and160160+ * is of variabled size. It consists of a sequence of variable size161161+ * USN_RECORDS. The minimum allocated_size is allocation_delta as162162+ * specified in $DATA/$Max. When the maximum_size specified in $DATA/$Max is163163+ * exceeded by more than allocation_delta bytes, allocation_delta bytes are164164+ * allocated and appended to the $DATA/$J attribute and an equal number of165165+ * bytes at the beginning of the attribute are freed and made sparse. Note the166166+ * making sparse only happens at volume checkpoints and hence the actual167167+ * $DATA/$J size can exceed maximum_size + allocation_delta temporarily.168168+ */169169+typedef struct {170170+/*Ofs*/171171+/* 0*/le32 length; /* Byte size of this record (8-byte172172+ aligned). */173173+/* 4*/le16 major_ver; /* Major version of the transaction log used174174+ for this record. */175175+/* 6*/le16 minor_ver; /* Minor version of the transaction log used176176+ for this record. */177177+/* 8*/leMFT_REF mft_reference;/* The mft reference of the file (or178178+ directory) described by this record. */179179+/*0x10*/leMFT_REF parent_directory;/* The mft reference of the parent180180+ directory of the file described by this181181+ record. */182182+/*0x18*/leUSN usn; /* The usn of this record. Equals the offset183183+ within the $DATA/$J attribute. */184184+/*0x20*/sle64 time; /* Time when this record was created. */185185+/*0x28*/USN_REASON_FLAGS reason;/* Reason flags (see above). */186186+/*0x2c*/USN_SOURCE_INFO_FLAGS source_info;/* Source info flags (see above). */187187+/*0x30*/le32 security_id; /* File security_id copied from188188+ $STANDARD_INFORMATION. */189189+/*0x34*/FILE_ATTR_FLAGS file_attributes; /* File attributes copied from190190+ $STANDARD_INFORMATION or $FILE_NAME (not191191+ sure which). */192192+/*0x38*/le16 file_name_size; /* Size of the file name in bytes. */193193+/*0x3a*/le16 file_name_offset; /* Offset to the file name in bytes from the194194+ start of this record. */195195+/*0x3c*/ntfschar file_name[0]; /* Use when creating only. When reading use196196+ file_name_offset to determine the location197197+ of the name. */198198+/* sizeof() = 60 (0x3c) bytes */199199+} __attribute__ ((__packed__)) USN_RECORD;200200+201201+extern BOOL ntfs_stamp_usnjrnl(ntfs_volume *vol);202202+203203+#endif /* NTFS_RW */204204+205205+#endif /* _LINUX_NTFS_USNJRNL_H */
+10-2
fs/ntfs/volume.h
···22 * volume.h - Defines for volume structures in NTFS Linux kernel driver. Part33 * of the Linux-NTFS project.44 *55- * Copyright (c) 2001-2004 Anton Altaparmakov55+ * Copyright (c) 2001-2005 Anton Altaparmakov66 * Copyright (c) 2002 Richard Russon77 *88 * This program/include file is free software; you can redistribute it and/or···5454 mode_t dmask; /* The mask for directory5555 permissions. */5656 u8 mft_zone_multiplier; /* Initial mft zone multiplier. */5757- u8 on_errors; /* What to do on file system errors. */5757+ u8 on_errors; /* What to do on filesystem errors. */5858 /* NTFS bootsector provided information. */5959 u16 sector_size; /* in bytes */6060 u8 sector_size_bits; /* log2(sector_size) */···125125 /* $Quota stuff is NTFS3.0+ specific. Unused/NULL otherwise. */126126 struct inode *quota_ino; /* The VFS inode of $Quota. */127127 struct inode *quota_q_ino; /* Attribute inode for $Quota/$Q. */128128+ /* $UsnJrnl stuff is NTFS3.0+ specific. Unused/NULL otherwise. */129129+ struct inode *usnjrnl_ino; /* The VFS inode of $UsnJrnl. */130130+ struct inode *usnjrnl_max_ino; /* Attribute inode for $UsnJrnl/$Max. */131131+ struct inode *usnjrnl_j_ino; /* Attribute inode for $UsnJrnl/$J. */128132#endif /* NTFS_RW */129133 struct nls_table *nls_map;130134} ntfs_volume;···145141 file names in WIN32 namespace. */146142 NV_LogFileEmpty, /* 1: $LogFile journal is empty. */147143 NV_QuotaOutOfDate, /* 1: $Quota is out of date. */144144+ NV_UsnJrnlStamped, /* 1: $UsnJrnl has been stamped. */145145+ NV_SparseEnabled, /* 1: May create sparse files. */148146} ntfs_volume_flags;149147150148/*···173167NVOL_FNS(CaseSensitive)174168NVOL_FNS(LogFileEmpty)175169NVOL_FNS(QuotaOutOfDate)170170+NVOL_FNS(UsnJrnlStamped)171171+NVOL_FNS(SparseEnabled)176172177173#endif /* _LINUX_NTFS_VOLUME_H */
···23232424#define raw_smp_processor_id() (current_thread_info()->cpu)25252626-extern cpumask_t cpu_present_mask;2727-#define cpu_possible_map cpu_present_mask2828-2926/*3027 * at the moment, there's not a big penalty for changing CPUs3128 * (the >big< penalty is running SMP in the first place)
+1
include/asm-ia64/pci.h
···128128 void *acpi_handle;129129 void *iommu;130130 int segment;131131+ int node; /* nearest node with memory or -1 for global allocation */131132132133 unsigned int windows;133134 struct pci_window *window;
···5353 long (*hpte_insert)(unsigned long hpte_group,5454 unsigned long va,5555 unsigned long prpn,5656- int secondary, 5757- unsigned long hpteflags, 5858- int bolted,5959- int large);5656+ unsigned long vflags,5757+ unsigned long rflags);6058 long (*hpte_remove)(unsigned long hpte_group);6159 void (*flush_hash_range)(unsigned long context,6260 unsigned long number,
+29-54
include/asm-ppc64/mmu.h
···60606161#define HPTES_PER_GROUP 862626363+#define HPTE_V_AVPN_SHIFT 76464+#define HPTE_V_AVPN ASM_CONST(0xffffffffffffff80)6565+#define HPTE_V_AVPN_VAL(x) (((x) & HPTE_V_AVPN) >> HPTE_V_AVPN_SHIFT)6666+#define HPTE_V_BOLTED ASM_CONST(0x0000000000000010)6767+#define HPTE_V_LOCK ASM_CONST(0x0000000000000008)6868+#define HPTE_V_LARGE ASM_CONST(0x0000000000000004)6969+#define HPTE_V_SECONDARY ASM_CONST(0x0000000000000002)7070+#define HPTE_V_VALID ASM_CONST(0x0000000000000001)7171+7272+#define HPTE_R_PP0 ASM_CONST(0x8000000000000000)7373+#define HPTE_R_TS ASM_CONST(0x4000000000000000)7474+#define HPTE_R_RPN_SHIFT 127575+#define HPTE_R_RPN ASM_CONST(0x3ffffffffffff000)7676+#define HPTE_R_FLAGS ASM_CONST(0x00000000000003ff)7777+#define HPTE_R_PP ASM_CONST(0x0000000000000003)7878+6379/* Values for PP (assumes Ks=0, Kp=1) */6480/* pp0 will always be 0 for linux */6581#define PP_RWXX 0 /* Supervisor read/write, User none */···85698670#ifndef __ASSEMBLY__87718888-/* Hardware Page Table Entry */8972typedef struct {9090- unsigned long avpn:57; /* vsid | api == avpn */9191- unsigned long : 2; /* Software use */9292- unsigned long bolted: 1; /* HPTE is "bolted" */9393- unsigned long lock: 1; /* lock on pSeries SMP */9494- unsigned long l: 1; /* Virtual page is large (L=1) or 4 KB (L=0) */9595- unsigned long h: 1; /* Hash function identifier */9696- unsigned long v: 1; /* Valid (v=1) or invalid (v=0) */9797-} Hpte_dword0;7373+ unsigned long v;7474+ unsigned long r;7575+} hpte_t;98769999-typedef struct {100100- unsigned long pp0: 1; /* Page protection bit 0 */101101- unsigned long ts: 1; /* Tag set bit */102102- unsigned long rpn: 50; /* Real page number */103103- unsigned long : 2; /* Reserved */104104- unsigned long ac: 1; /* Address compare */ 105105- unsigned long r: 1; /* Referenced */106106- unsigned long c: 1; /* Changed */107107- unsigned long w: 1; /* Write-thru cache mode */108108- unsigned long i: 1; /* Cache inhibited */109109- unsigned long m: 1; /* Memory coherence required */110110- unsigned long g: 1; /* Guarded */111111- unsigned long n: 1; /* No-execute */112112- unsigned long pp: 2; /* Page protection bits 1:2 */113113-} Hpte_dword1;114114-115115-typedef struct {116116- char padding[6]; /* padding */117117- unsigned long : 6; /* padding */ 118118- unsigned long flags: 10; /* HPTE flags */119119-} Hpte_dword1_flags;120120-121121-typedef struct {122122- union {123123- unsigned long dword0;124124- Hpte_dword0 dw0;125125- } dw0;126126-127127- union {128128- unsigned long dword1;129129- Hpte_dword1 dw1;130130- Hpte_dword1_flags flags;131131- } dw1;132132-} HPTE; 133133-134134-extern HPTE * htab_address;135135-extern unsigned long htab_hash_mask;7777+extern hpte_t *htab_address;7878+extern unsigned long htab_hash_mask;1367913780static inline unsigned long hpt_hash(unsigned long vpn, int large)13881{···156181 asm volatile("ptesync": : :"memory");157182}158183159159-static inline unsigned long slot2va(unsigned long avpn, unsigned long large,160160- unsigned long secondary, unsigned long slot)184184+static inline unsigned long slot2va(unsigned long hpte_v, unsigned long slot)161185{186186+ unsigned long avpn = HPTE_V_AVPN_VAL(hpte_v);162187 unsigned long va;163188164189 va = avpn << 23;165190166166- if (!large) {191191+ if (! (hpte_v & HPTE_V_LARGE)) {167192 unsigned long vpi, pteg;168193169194 pteg = slot / HPTES_PER_GROUP;170170- if (secondary)195195+ if (hpte_v & HPTE_V_SECONDARY)171196 pteg = ~pteg;172197173198 vpi = ((va >> 28) ^ pteg) & htab_hash_mask;···194219195220extern long pSeries_lpar_hpte_insert(unsigned long hpte_group,196221 unsigned long va, unsigned long prpn,197197- int secondary, unsigned long hpteflags,198198- int bolted, int large);222222+ unsigned long vflags,223223+ unsigned long rflags);199224extern long native_hpte_insert(unsigned long hpte_group, unsigned long va,200200- unsigned long prpn, int secondary,201201- unsigned long hpteflags, int bolted, int large);225225+ unsigned long prpn,226226+ unsigned long vflags, unsigned long rflags);202227203228#endif /* __ASSEMBLY__ */204229
···55#define POSIX_FADV_RANDOM 1 /* Expect random page references. */66#define POSIX_FADV_SEQUENTIAL 2 /* Expect sequential page references. */77#define POSIX_FADV_WILLNEED 3 /* Will need these pages. */88+99+/*1010+ * The advise values for POSIX_FADV_DONTNEED and POSIX_ADV_NOREUSE1111+ * for s390-64 differ from the values for the rest of the world.1212+ */1313+#if defined(__s390x__)1414+#define POSIX_FADV_DONTNEED 6 /* Don't need these pages. */1515+#define POSIX_FADV_NOREUSE 7 /* Data will be accessed once. */1616+#else817#define POSIX_FADV_DONTNEED 4 /* Don't need these pages. */918#define POSIX_FADV_NOREUSE 5 /* Data will be accessed once. */1919+#endif10201121#endif /* FADVISE_H_INCLUDED */
+3
include/linux/fs.h
···14411441extern void generic_delete_inode(struct inode *inode);14421442extern void generic_drop_inode(struct inode *inode);1443144314441444+extern struct inode *ilookup5_nowait(struct super_block *sb,14451445+ unsigned long hashval, int (*test)(struct inode *, void *),14461446+ void *data);14441447extern struct inode *ilookup5(struct super_block *sb, unsigned long hashval,14451448 int (*test)(struct inode *, void *), void *data);14461449extern struct inode *ilookup(struct super_block *sb, unsigned long ino);
···262262int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors);263263void bitmap_endwrite(struct bitmap *bitmap, sector_t offset, unsigned long sectors,264264 int success);265265-int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks);265265+int bitmap_start_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int degraded);266266void bitmap_end_sync(struct bitmap *bitmap, sector_t offset, int *blocks, int aborted);267267void bitmap_close_sync(struct bitmap *bitmap);268268
+4-2
include/linux/serial.h
···174174175175176176#ifdef __KERNEL__177177+#include <linux/compiler.h>178178+177179/* Export to allow PCMCIA to use this - Dave Hinds */178178-extern int register_serial(struct serial_struct *req);179179-extern void unregister_serial(int line);180180+extern int __deprecated register_serial(struct serial_struct *req);181181+extern void __deprecated unregister_serial(int line);180182181183/* Allow architectures to override entries in serial8250_ports[] at run time: */182184struct uart_port; /* forward declaration */
-1
include/linux/serialP.h
···1919 * For definitions of the flags field, see tty.h2020 */21212222-#include <linux/version.h>2322#include <linux/config.h>2423#include <linux/termios.h>2524#include <linux/workqueue.h>
···6161 CTL_DEV=7, /* Devices */6262 CTL_BUS=8, /* Busses */6363 CTL_ABI=9, /* Binary emulation */6464- CTL_CPU=10, /* CPU stuff (speed scaling, etc) */6565- CTL_INOTIFY=11 /* Inotify */6464+ CTL_CPU=10 /* CPU stuff (speed scaling, etc) */6665};67666867/* CTL_BUS names: */···7071 CTL_BUS_ISA=1 /* ISA */7172};72737373-/* CTL_INOTIFY names: */7474+/* /proc/sys/fs/inotify/ */7475enum7576{7676- INOTIFY_MAX_USER_DEVICES=1, /* max number of inotify device instances per user */7777- INOTIFY_MAX_USER_WATCHES=2, /* max number of inotify watches per user */7878- INOTIFY_MAX_QUEUED_EVENTS=3 /* Max number of queued events per inotify device instance */7777+ INOTIFY_MAX_USER_INSTANCES=1, /* max instances per user */7878+ INOTIFY_MAX_USER_WATCHES=2, /* max watches per user */7979+ INOTIFY_MAX_QUEUED_EVENTS=3 /* max queued events per instance */7980};80818182/* CTL_KERN names: */···684685 FS_XFS=17, /* struct: control xfs parameters */685686 FS_AIO_NR=18, /* current system-wide number of aio requests */686687 FS_AIO_MAX_NR=19, /* system-wide maximum number of aio requests */688688+ FS_INOTIFY=20, /* inotify submenu */687689};688690689691/* /proc/sys/fs/quota/ */
-2
init/do_mounts.c
···2626/* this is initialized in init/main.c */2727dev_t ROOT_DEV;28282929-EXPORT_SYMBOL(ROOT_DEV);3030-3129static int __init load_ramdisk(char *str)3230{3331 rd_doload = simple_strtol(str,NULL,0) & 3;
···6868 if (unlikely(IS_ERR(page))) {6969 if (PTR_ERR(page) == -ENODATA) {7070 /* sparse */7171- page = virt_to_page(empty_zero_page);7171+ page = ZERO_PAGE(0);7272 } else {7373 desc->error = PTR_ERR(page);7474 goto out;7575 }7676- } else7777- BUG_ON(!PageUptodate(page));7676+ }78777978 /* If users can be writing to this page using arbitrary8079 * virtual addresses, take care about potential aliasing···8384 flush_dcache_page(page);84858586 /*8686- * Ok, we have the page, and it's up-to-date, so8787- * now we can copy it to user space...8787+ * Ok, we have the page, so now we can copy it to user space...8888 *8989 * The actor routine returns how many bytes were actually used..9090 * NOTE! This may not be the same as how much of a user buffer···162164 * xip_write163165 *164166 * This function walks all vmas of the address_space and unmaps the165165- * empty_zero_page when found at pgoff. Should it go in rmap.c?167167+ * ZERO_PAGE when found at pgoff. Should it go in rmap.c?166168 */167169static void168170__xip_unmap (struct address_space * mapping,···185187 * We need the page_table_lock to protect us from page faults,186188 * munmap, fork, etc...187189 */188188- pte = page_check_address(virt_to_page(empty_zero_page), mm,190190+ pte = page_check_address(ZERO_PAGE(address), mm,189191 address);190192 if (!IS_ERR(pte)) {191193 /* Nuke the page table entry. */···228230229231 page = mapping->a_ops->get_xip_page(mapping, pgoff*(PAGE_SIZE/512), 0);230232 if (!IS_ERR(page)) {231231- BUG_ON(!PageUptodate(page));232233 return page;233234 }234235 if (PTR_ERR(page) != -ENODATA)···242245 pgoff*(PAGE_SIZE/512), 1);243246 if (IS_ERR(page))244247 return NULL;245245- BUG_ON(!PageUptodate(page));246248 /* unmap page at pgoff from all other vmas */247249 __xip_unmap(mapping, pgoff);248250 } else {249249- /* not shared and writable, use empty_zero_page */250250- page = virt_to_page(empty_zero_page);251251+ /* not shared and writable, use ZERO_PAGE() */252252+ page = ZERO_PAGE(address);251253 }252254253255 return page;···314318 status = PTR_ERR(page);315319 break;316320 }317317-318318- BUG_ON(!PageUptodate(page));319321320322 copied = filemap_copy_from_user(page, offset, buf, bytes);321323 flush_dcache_page(page);···429435 return 0;430436 else431437 return PTR_ERR(page);432432- } else433433- BUG_ON(!PageUptodate(page));438438+ }434439 kaddr = kmap_atomic(page, KM_USER0);435440 memset(kaddr + offset, 0, length);436441 kunmap_atomic(kaddr, KM_USER0);