S: Iasi 6600
S: Romania
+ N: Mark Adler
+ E: madler@alumni.caltech.edu
+ W: http://alumnus.caltech.edu/~madler/
+ D: zlib decompression
+
N: Monalisa Agrawal
E: magrawal@nortelnetworks.com
D: Basic Interphase 5575 driver with UBR and ABR support.
S: Czech Republic
N: Niels Kristian Bech Jensen
- E: nkbj@image.dk
- W: http://www.image.dk/~nkbj
+ E: nkbj1970@hotmail.com
D: Miscellaneous kernel updates and fixes.
- S: Dr. Holsts Vej 34, lejl. 164
- S: DK-8230 Åbyhøj
- S: Denmark
N: Michael K. Johnson
E: johnsonm@redhat.com
N: Thibaut Varene
E: T-Bone@parisc-linux.org
- W: http://www.parisc-linux.org/
+ W: http://www.parisc-linux.org/~varenet/
P: 1024D/B7D2F063 E67C 0D43 A75E 12A5 BB1C FA2F 1E32 C3DA B7D2 F063
D: PA-RISC port minion, PDC and GSCPS2 drivers, debuglocks and other bits
- D: Some bits in an ARM port, S1D13XXX FB driver, random patches here and there
+ D: Some ARM at91rm9200 bits, S1D13XXX FB driver, random patches here and there
D: AD1889 sound driver
S: Paris, France
S: USA
N: Steven Whitehouse
-E: SteveW@ACM.org
+E: steve@chygwyn.com
W: http://www.chygwyn.com/~steve
-D: Linux DECnet project: http://www.sucs.swan.ac.uk/~rohan/DECnet/index.html
+D: Linux DECnet project
D: Minor debugging of other networking protocols.
-D: Misc bug fixes and filesystem development
+D: Misc bug fixes and GFS2 filesystem development
N: Hans-Joachim Widmaier
E: hjw@zvw.de
L: linux-aio@kvack.org
S: Supported
+ ABIT UGURU HARDWARE MONITOR DRIVER
+ P: Hans de Goede
+ M: j.w.r.degoede@hhs.nl
+ L: lm-sensors@lm-sensors.org
+ S: Maintained
+
ACENIC DRIVER
P: Jes Sorensen
M: jes@trained-monkey.org
W: http://www.penguinppc.org/ppc64/
S: Supported
+ BROADCOM B44 10/100 ETHERNET DRIVER
+ P: Gary Zambrano
+ M: zambrano@broadcom.com
+ L: netdev@vger.kernel.org
+ S: Supported
+
BROADCOM BNX2 GIGABIT ETHERNET DRIVER
P: Michael Chan
M: mchan@broadcom.com
L: linux-kernel@vger.kernel.org
S: Maintained
+DISTRIBUTED LOCK MANAGER
+P: Patrick Caulfield
+M: pcaulfie@redhat.com
+P: David Teigland
+M: teigland@redhat.com
+L: cluster-devel@redhat.com
+W: http://sources.redhat.com/cluster/
+T: git kernel.org:/pub/scm/linux/kernel/git/steve/gfs-2.6.git
+S: Supported
+
DAVICOM FAST ETHERNET (DMFE) NETWORK DRIVER
P: Tobias Ringstrom
M: tori@unhappy.mine.nu
EDAC-CORE
P: Doug Thompson
- M: norsk5@xmission.com, dthompson@linuxnetworx.com
- P: Dave Peterson
- M: dsp@llnl.gov, dave_peterson@pobox.com
+ M: norsk5@xmission.com
L: bluesmoke-devel@lists.sourceforge.net
W: bluesmoke.sourceforge.net
- S: Maintained
+ S: Supported
EDAC-E752X
- P: Dave Peterson
- M: dsp@llnl.gov, dave_peterson@pobox.com
+ P: Mark Gross
+ M: mark.gross@intel.com
L: bluesmoke-devel@lists.sourceforge.net
W: bluesmoke.sourceforge.net
S: Maintained
EDAC-E7XXX
- P: Dave Peterson
- M: dsp@llnl.gov, dave_peterson@pobox.com
+ P: Doug Thompson
+ M: norsk5@xmission.com
L: bluesmoke-devel@lists.sourceforge.net
W: bluesmoke.sourceforge.net
S: Maintained
W: http://www.kernel.org/pub/linux/utils/net/hdlc/
S: Maintained
+GFS2 FILE SYSTEM
+P: Steven Whitehouse
+M: swhiteho@redhat.com
+L: cluster-devel@redhat.com
+W: http://sources.redhat.com/cluster/
+T: git kernel.org:/pub/scm/linux/kernel/git/steve/gfs-2.6.git
+S: Supported
+
GIGASET ISDN DRIVERS
P: Hansjoerg Lipp
M: hjlipp@web.de
W: http://www.lm-sensors.nu/
S: Maintained
+ HARDWARE RANDOM NUMBER GENERATOR CORE
+ P: Michael Buesch
+ M: mb@bu3sch.de
+ S: Maintained
+
HARD DRIVE ACTIVE PROTECTION SYSTEM (HDAPS) DRIVER
P: Robert Love
M: rlove@rlove.org
W: http://www.nt.tuwien.ac.at/~kkudielk/Linux/
S: Maintained
+ HIGHPOINT ROCKETRAID 3xxx RAID DRIVER
+ P: HighPoint Linux Team
+ M: linux@highpoint-tech.com
+ W: http://www.highpoint-tech.com
+ S: Supported
+
HIPPI
P: Jes Sorensen
M: jes@trained-monkey.org
INPUT (KEYBOARD, MOUSE, JOYSTICK) DRIVERS
P: Dmitry Torokhov
- M: dtor_core@ameritech.net
+ M: dmitry.torokhov@gmail.com
+ M: dtor@mail.ru
L: linux-input@atrey.karlin.mff.cuni.cz
L: linux-joystick@atrey.karlin.mff.cuni.cz
T: git kernel.org:/pub/scm/linux/kernel/git/dtor/input.git
M: tigran@veritas.com
S: Maintained
+ INTEL IXP4XX RANDOM NUMBER GENERATOR SUPPORT
+ P: Deepak Saxena
+ M: dsaxena@plexity.net
+ S: Maintained
+
INTEL PRO/100 ETHERNET SUPPORT
P: John Ronciak
M: john.ronciak@intel.com
W: http://megaraid.lsilogic.com
S: Maintained
- MEMORY TECHNOLOGY DEVICES
+ MEMORY TECHNOLOGY DEVICES (MTD)
P: David Woodhouse
M: dwmw2@infradead.org
W: http://www.linux-mtd.infradead.org/
L: linux-mtd@lists.infradead.org
- T: git kernel.org:/pub/scm/linux/kernel/git/tglx/mtd-2.6.git
+ T: git git://git.infradead.org/mtd-2.6.git
S: Maintained
MICROTEK X6 SCANNER
W: http://www.atnf.csiro.au/~rgooch/linux/kernel-patches.html
S: Maintained
- MULTIMEDIA CARD SUBSYSTEM
+ MULTIMEDIA CARD (MMC) SUBSYSTEM
P: Russell King
M: rmk+mmc@arm.linux.org.uk
S: Maintained
L: linux-fbdev-devel@lists.sourceforge.net
S: Maintained
+ OPENCORES I2C BUS DRIVER
+ P: Peter Korsgaard
+ M: jacmet@sunsite.dk
+ L: lm-sensors@lm-sensors.org
+ S: Maintained
+
ORACLE CLUSTER FILESYSTEM 2 (OCFS2)
P: Mark Fasheh
M: mark.fasheh@oracle.com
W: http://www.winischhofer.at/linuxsisusbvga.shtml
S: Maintained
- SMSC47M1 HARDWARE MONITOR DRIVER
- P: Jean Delvare
- M: khali@linux-fr.org
- L: lm-sensors@lm-sensors.org
- S: Odd Fixes
-
- SMB FILESYSTEM
- P: Urban Widmark
- M: urban@teststation.com
- W: http://samba.org/
- L: samba@samba.org
- S: Maintained
-
SMC91x ETHERNET DRIVER
P: Nicolas Pitre
M: nico@cam.org
M: hch@infradead.org
S: Maintained
+ TI OMAP RANDOM NUMBER GENERATOR SUPPORT
+ P: Deepak Saxena
+ M: dsaxena@plexity.net
+ S: Maintained
+
TI PARALLEL LINK CABLE DRIVER
P: Romain Lievin
M: roms@lpg.ticalc.org
W: http://projects.drzeus.cx/wbsd
S: Maintained
- W83L785TS HARDWARE MONITOR DRIVER
- P: Jean Delvare
- M: khali@linux-fr.org
- L: lm-sensors@lm-sensors.org
- S: Odd Fixes
-
WATCHDOG DEVICE DRIVERS
P: Wim Van Sebroeck
M: wim@iguana.be
P: Silicon Graphics Inc
M: xfs-masters@oss.sgi.com
M: nathans@sgi.com
- L: linux-xfs@oss.sgi.com
+ L: xfs@oss.sgi.com
W: http://oss.sgi.com/projects/xfs
S: Supported
config EXT2_FS_XIP
bool "Ext2 execute in place support"
- depends on EXT2_FS
+ depends on EXT2_FS && MMU
help
Execute in place can be used on memory-backed block devices. If you
enable this option, you can select to mount block devices which are
default n
source "fs/xfs/Kconfig"
+source "fs/gfs2/Kconfig"
config OCFS2_FS
tristate "OCFS2 file system support (EXPERIMENTAL)"
- depends on NET && EXPERIMENTAL
+ depends on NET && SYSFS && EXPERIMENTAL
select CONFIGFS_FS
select JBD
select CRC32
- POSIX ACLs
- readpages / writepages (not user visible)
+ config OCFS2_DEBUG_MASKLOG
+ bool "OCFS2 logging support"
+ depends on OCFS2_FS
+ default y
+ help
+ The ocfs2 filesystem has an extensive logging system. The system
+ allows selection of events to log via files in /sys/o2cb/logmask/.
+ This option will enlarge your kernel, but it allows debugging of
+ ocfs2 filesystem issues.
+
config MINIX_FS
tristate "Minix fs support"
help
bool "Inotify file change notification support"
default y
---help---
- Say Y here to enable inotify support and the associated system
- calls. Inotify is a file change notification system and a
- replacement for dnotify. Inotify fixes numerous shortcomings in
- dnotify and introduces several new features. It allows monitoring
- of both files and directories via a single open fd. Other features
- include multiple file events, one-shot support, and unmount
+ Say Y here to enable inotify support. Inotify is a file change
+ notification system and a replacement for dnotify. Inotify fixes
+ numerous shortcomings in dnotify and introduces several new features
+ including multiple file events, one-shot support, and unmount
notification.
For more information, see Documentation/filesystems/inotify.txt
If unsure, say Y.
+ config INOTIFY_USER
+ bool "Inotify support for userspace"
+ depends on INOTIFY
+ default y
+ ---help---
+ Say Y here to enable inotify support for userspace, including the
+ associated system calls. Inotify allows monitoring of both files and
+ directories via a single open fd. Events are read from the file
+ descriptor, which is also select()- and poll()-able.
+
+ For more information, see Documentation/filesystems/inotify.txt
+
+ If unsure, say Y.
+
config QUOTA
bool "Quota support"
help
menu "Pseudo filesystems"
config PROC_FS
- bool "/proc file system support"
+ bool "/proc file system support" if EMBEDDED
+ default y
help
This is a virtual file system providing information about the status
of the system. "Virtual" means that it doesn't take up any space on
If unsure, say 'N'.
+ config JFFS2_FS_XATTR
+ bool "JFFS2 XATTR support (EXPERIMENTAL)"
+ depends on JFFS2_FS && EXPERIMENTAL
+ default n
+ help
+ Extended attributes are name:value pairs associated with inodes by
+ the kernel or by users (see the attr(5) manual page, or visit
+ <http://acl.bestbits.at/> for details).
+
+ If unsure, say N.
+
+ config JFFS2_FS_POSIX_ACL
+ bool "JFFS2 POSIX Access Control Lists"
+ depends on JFFS2_FS_XATTR
+ default y
+ select FS_POSIX_ACL
+ help
+ Posix Access Control Lists (ACLs) support permissions for users and
+ groups beyond the owner/group/world scheme.
+
+ To learn more about Access Control Lists, visit the Posix ACLs for
+ Linux website <http://acl.bestbits.at/>.
+
+ If you don't know what Access Control Lists are, say N
+
+ config JFFS2_FS_SECURITY
+ bool "JFFS2 Security Labels"
+ depends on JFFS2_FS_XATTR
+ default y
+ help
+ Security labels support alternative access control models
+ implemented by security modules like SELinux. This option
+ enables an extended attribute handler for file security
+ labels in the jffs2 filesystem.
+
+ If you are not using a security module that requires using
+ extended attributes for file security labels, say N.
+
config JFFS2_COMPRESSION_OPTIONS
bool "Advanced compression options for JFFS2"
depends on JFFS2_FS
config UFS_FS_WRITE
bool "UFS file system write support (DANGEROUS)"
- depends on UFS_FS && EXPERIMENTAL && BROKEN
+ depends on UFS_FS && EXPERIMENTAL
help
Say Y here if you want to try writing to UFS partitions. This is
experimental, so you should back up your UFS partitions beforehand.
+ config UFS_DEBUG
+ bool "UFS debugging"
+ depends on UFS_FS
+ help
+ If you are experiencing any problems with the UFS filesystem, say
+ Y here. This will result in _many_ additional debugging messages to be
+ written to the system log.
+
endmenu
menu "Network File Systems"
select LOCKD
select SUNRPC
select EXPORTFS
- select NFS_ACL_SUPPORT if NFSD_V3_ACL || NFSD_V2_ACL
+ select NFSD_V2_ACL if NFSD_V3_ACL
+ select NFS_ACL_SUPPORT if NFSD_V2_ACL
+ select NFSD_TCP if NFSD_V4
+ select CRYPTO_MD5 if NFSD_V4
+ select CRYPTO if NFSD_V4
+ select FS_POSIX_ACL if NFSD_V4
help
If you want your Linux box to act as an NFS *server*, so that other
computers on your local network which support NFS can access certain
config NFSD_V3_ACL
bool "Provide server support for the NFSv3 ACL protocol extension"
depends on NFSD_V3
- select NFSD_V2_ACL
help
Implement the NFSv3 ACL protocol extension for manipulating POSIX
Access Control Lists on exported file systems. NFS clients should
config NFSD_V4
bool "Provide NFSv4 server support (EXPERIMENTAL)"
depends on NFSD_V3 && EXPERIMENTAL
- select NFSD_TCP
- select CRYPTO_MD5
- select CRYPTO
- select FS_POSIX_ACL
help
If you would like to include the NFSv4 server as well as the NFSv2
and NFSv3 servers, say Y here. This feature is experimental, and
mounted by the cifs client to be displayed in /proc/fs/cifs/Stats
config CIFS_STATS2
- bool "CIFS extended statistics"
+ bool "Extended statistics"
depends on CIFS_STATS
help
Enabling this option will allow more detailed statistics on SMB
Unless you are a developer or are doing network performance analysis
or tuning, say N.
+ config CIFS_WEAK_PW_HASH
+ bool "Support legacy servers which use weaker LANMAN security"
+ depends on CIFS
+ help
+ Modern CIFS servers including Samba and most Windows versions
+ (since 1997) support stronger NTLM (and even NTLMv2 and Kerberos)
+ security mechanisms. These hash the password more securely
+ than the mechanisms used in the older LANMAN version of the
+ SMB protocol needed to establish sessions with old SMB servers.
+
+ Enabling this option allows the cifs module to mount to older
+ LANMAN based servers such as OS/2 and Windows 95, but such
+ mounts may be less secure than mounts using NTLM or more recent
+ security mechanisms if you are on a public network. Unless you
+ have a need to access old SMB servers (and are on a private
+ network) you probably want to say N. Even if this support
+ is enabled in the kernel build, they will not be used
+ automatically. At runtime LANMAN mounts are disabled but
+ can be set to required (or optional) either in
+ /proc/fs/cifs (see fs/cifs/README for more detail) or via an
+ option on the mount command. This support is disabled by
+ default in order to reduce the possibility of a downgrade
+ attack.
+
+ If unsure, say N.
+
config CIFS_XATTR
bool "CIFS extended attributes"
depends on CIFS
(such as Samba 3.10 and later) which can negotiate
CIFS POSIX ACL support. If unsure, say N.
+ config CIFS_DEBUG2
+ bool "Enable additional CIFS debugging routines"
+ help
+ Enabling this option adds a few more debugging routines
+ to the cifs code which slightly increases the size of
+ the cifs module and can cause additional logging of debug
+ messages in some error paths, slowing performance. This
+ option can be turned off unless you are debugging
+ cifs problems. If unsure, say N.
+
config CIFS_EXPERIMENTAL
bool "CIFS Experimental Features (EXPERIMENTAL)"
depends on CIFS && EXPERIMENTAL
If unsure, say N.
config CIFS_UPCALL
- bool "CIFS Kerberos/SPNEGO advanced session setup (EXPERIMENTAL)"
+ bool "Kerberos/SPNEGO advanced session setup (EXPERIMENTAL)"
depends on CIFS_EXPERIMENTAL
select CONNECTOR
help
endmenu
source "fs/nls/Kconfig"
+source "fs/dlm/Kconfig"
endmenu
ioprio.o pnode.o drop_caches.o splice.o sync.o
obj-$(CONFIG_INOTIFY) += inotify.o
+ obj-$(CONFIG_INOTIFY_USER) += inotify_user.o
obj-$(CONFIG_EPOLL) += eventpoll.o
obj-$(CONFIG_COMPAT) += compat.o compat_ioctl.o
obj-y += devpts/
obj-$(CONFIG_PROFILING) += dcookies.o
+obj-$(CONFIG_DLM) += dlm/
# Do not add any filesystems before this line
obj-$(CONFIG_REISERFS_FS) += reiserfs/
obj-$(CONFIG_VFAT_FS) += vfat/
obj-$(CONFIG_BFS_FS) += bfs/
obj-$(CONFIG_ISO9660_FS) += isofs/
- obj-$(CONFIG_DEVFS_FS) += devfs/
obj-$(CONFIG_HFSPLUS_FS) += hfsplus/ # Before hfs to find wrapped HFS+
obj-$(CONFIG_HFS_FS) += hfs/
obj-$(CONFIG_VXFS_FS) += freevxfs/
obj-$(CONFIG_HPPFS) += hppfs/
obj-$(CONFIG_DEBUG_FS) += debugfs/
obj-$(CONFIG_OCFS2_FS) += ocfs2/
+obj-$(CONFIG_GFS2_FS) += gfs2/
* structures etc.
*/
- #include <linux/config.h>
#include <linux/limits.h>
#include <linux/ioctl.h>
struct page* (*get_xip_page)(struct address_space *, sector_t,
int);
/* migrate the contents of a page to the specified target */
- int (*migratepage) (struct page *, struct page *);
+ int (*migratepage) (struct address_space *,
+ struct page *, struct page *);
};
struct backing_dev_info;
unsigned int truncate_count; /* Cover race condition with truncate */
unsigned long nrpages; /* number of total pages */
pgoff_t writeback_index;/* writeback starts here */
- struct address_space_operations *a_ops; /* methods */
+ const struct address_space_operations *a_ops; /* methods */
unsigned long flags; /* error bits/gfp mask */
struct backing_dev_info *backing_dev_info; /* device readahead, etc */
spinlock_t private_lock; /* for use by the address_space */
#define FL_FLOCK 2
#define FL_ACCESS 8 /* not trying to lock, just looking */
#define FL_LEASE 32 /* lease held on this file */
+ #define FL_CLOSE 64 /* unlock on close */
#define FL_SLEEP 128 /* A blocking lock */
/*
extern int posix_lock_file(struct file *, struct file_lock *);
extern int posix_lock_file_wait(struct file *, struct file_lock *);
extern int posix_unblock_lock(struct file *, struct file_lock *);
- extern int posix_locks_deadlock(struct file_lock *, struct file_lock *);
extern int flock_lock_file_wait(struct file *filp, struct file_lock *fl);
extern int __break_lease(struct inode *inode, unsigned int flags);
extern void lease_get_mtime(struct inode *, struct timespec *time);
extern int lease_modify(struct file_lock **, int);
extern int lock_may_read(struct inode *, loff_t start, unsigned long count);
extern int lock_may_write(struct inode *, loff_t start, unsigned long count);
- extern void steal_locks(fl_owner_t from);
struct fasync_struct {
int magic;
long (*compat_ioctl) (struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct inode *, struct file *);
- int (*flush) (struct file *);
+ int (*flush) (struct file *, fl_owner_t id);
int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, struct dentry *, int datasync);
int (*aio_fsync) (struct kiocb *, int datasync);
int (*sync_fs)(struct super_block *sb, int wait);
void (*write_super_lockfs) (struct super_block *);
void (*unlockfs) (struct super_block *);
- int (*statfs) (struct super_block *, struct kstatfs *);
+ int (*statfs) (struct dentry *, struct kstatfs *);
int (*remount_fs) (struct super_block *, int *, char *);
void (*clear_inode) (struct inode *);
- void (*umount_begin) (struct super_block *);
+ void (*umount_begin) (struct vfsmount *, int);
int (*show_options)(struct seq_file *, struct vfsmount *);
int (*show_stats)(struct seq_file *, struct vfsmount *);
struct file_system_type {
const char *name;
int fs_flags;
- struct super_block *(*get_sb) (struct file_system_type *, int,
- const char *, void *);
+ int (*get_sb) (struct file_system_type *, int,
+ const char *, void *, struct vfsmount *);
void (*kill_sb) (struct super_block *);
struct module *owner;
struct file_system_type * next;
struct list_head fs_supers;
};
- struct super_block *get_sb_bdev(struct file_system_type *fs_type,
+ extern int get_sb_bdev(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data,
- int (*fill_super)(struct super_block *, void *, int));
- struct super_block *get_sb_single(struct file_system_type *fs_type,
+ int (*fill_super)(struct super_block *, void *, int),
+ struct vfsmount *mnt);
+ extern int get_sb_single(struct file_system_type *fs_type,
int flags, void *data,
- int (*fill_super)(struct super_block *, void *, int));
- struct super_block *get_sb_nodev(struct file_system_type *fs_type,
+ int (*fill_super)(struct super_block *, void *, int),
+ struct vfsmount *mnt);
+ extern int get_sb_nodev(struct file_system_type *fs_type,
int flags, void *data,
- int (*fill_super)(struct super_block *, void *, int));
+ int (*fill_super)(struct super_block *, void *, int),
+ struct vfsmount *mnt);
void generic_shutdown_super(struct super_block *sb);
void kill_block_super(struct super_block *sb);
void kill_anon_super(struct super_block *sb);
int (*test)(struct super_block *,void *),
int (*set)(struct super_block *,void *),
void *data);
- struct super_block *get_sb_pseudo(struct file_system_type *, char *,
- struct super_operations *ops, unsigned long);
+ extern int get_sb_pseudo(struct file_system_type *, char *,
+ struct super_operations *ops, unsigned long,
+ struct vfsmount *mnt);
+ extern int simple_set_mnt(struct vfsmount *mnt, struct super_block *sb);
int __put_super(struct super_block *sb);
int __put_super_and_need_restart(struct super_block *sb);
void unnamed_dev_init(void);
extern void mnt_set_mountpoint(struct vfsmount *, struct dentry *,
struct vfsmount *);
- extern int vfs_statfs(struct super_block *, struct kstatfs *);
+ extern int vfs_statfs(struct dentry *, struct kstatfs *);
/* /sys/fs */
extern struct subsystem fs_subsys;
#define FLOCK_VERIFY_READ 1
#define FLOCK_VERIFY_WRITE 2
+/* /sys/fs */
+extern struct subsystem fs_subsys;
+
extern int locks_mandatory_locked(struct inode *);
extern int locks_mandatory_area(int, struct inode *, struct file *, loff_t, size_t);
extern void bdput(struct block_device *);
extern struct block_device *open_by_devnum(dev_t, unsigned);
extern const struct file_operations def_blk_fops;
- extern struct address_space_operations def_blk_aops;
+ extern const struct address_space_operations def_blk_aops;
extern const struct file_operations def_chr_fops;
extern const struct file_operations bad_sock_fops;
extern const struct file_operations def_fifo_fops;
extern loff_t dcache_dir_lseek(struct file *, loff_t, int);
extern int dcache_readdir(struct file *, void *, filldir_t);
extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *);
- extern int simple_statfs(struct super_block *, struct kstatfs *);
+ extern int simple_statfs(struct dentry *, struct kstatfs *);
extern int simple_link(struct dentry *, struct inode *, struct dentry *);
extern int simple_unlink(struct inode *, struct dentry *);
extern int simple_rmdir(struct inode *, struct dentry *);
struct tree_descr { char *name; const struct file_operations *ops; int mode; };
struct dentry *d_alloc_name(struct dentry *, const char *);
extern int simple_fill_super(struct super_block *, int, struct tree_descr *);
- extern int simple_pin_fs(char *name, struct vfsmount **mount, int *count);
+ extern int simple_pin_fs(struct file_system_type *, struct vfsmount **mount, int *count);
extern void simple_release_fs(struct vfsmount **mount, int *count);
extern ssize_t simple_read_from_buffer(void __user *, size_t, loff_t *, const void *, size_t);
#ifdef CONFIG_MIGRATION
- extern int buffer_migrate_page(struct page *, struct page *);
+ extern int buffer_migrate_page(struct address_space *,
+ struct page *, struct page *);
#else
#define buffer_migrate_page NULL
#endif
#define LONG_MAX ((long)(~0UL>>1))
#define LONG_MIN (-LONG_MAX - 1)
#define ULONG_MAX (~0UL)
+ #define LLONG_MAX ((long long)(~0ULL>>1))
+ #define LLONG_MIN (-LLONG_MAX - 1)
+ #define ULLONG_MAX (~0ULL)
#define STACK_MAGIC 0xdeadbeef
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define ALIGN(x,a) (((x)+(a)-1)&~((a)-1))
+#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
+ #define FIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
#define KERN_EMERG "<0>" /* system is unusable */
#define KERN_ALERT "<1>" /* action must be taken immediately */
# define might_sleep() do { might_resched(); } while (0)
#endif
- #define might_sleep_if(cond) do { if (unlikely(cond)) might_sleep(); } while (0)
+ #define might_sleep_if(cond) do { if (cond) might_sleep(); } while (0)
#define abs(x) ({ \
int __x = (x); \
__attribute__ ((format (printf, 3, 4)));
extern int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
__attribute__ ((format (printf, 3, 0)));
+ extern char *kasprintf(gfp_t gfp, const char *fmt, ...)
+ __attribute__ ((format (printf, 2, 3)));
extern int sscanf(const char *, const char *, ...)
__attribute__ ((format (scanf, 2, 3)));
/* Force a compilation error if condition is true */
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))
+ /* Force a compilation error if condition is true, but also produce a
+ result (of value 0 and type size_t), so the expression can be used
+ e.g. in a structure initializer (or where-ever else comma expressions
+ aren't permitted). */
+ #define BUILD_BUG_ON_ZERO(e) (sizeof(char[1 - 2 * !!(e)]) - 1)
+
/* Trap pasters of __FUNCTION__ at compile-time */
#define __FUNCTION__ (__func__)
#include <linux/console.h>
#include <linux/init.h>
#include <linux/module.h>
+ #include <linux/moduleparam.h>
#include <linux/interrupt.h> /* For in_interrupt() */
- #include <linux/config.h>
#include <linux/delay.h>
#include <linux/smp.h>
#include <linux/security.h>
struct console *con;
for (con = console_drivers; con; con = con->next) {
- if ((con->flags & CON_ENABLED) && con->write)
+ if ((con->flags & CON_ENABLED) && con->write &&
+ (cpu_online(smp_processor_id()) ||
+ (con->flags & CON_ANYTIME)))
con->write(con, &LOG_BUF(start), end - start);
}
}
#else
static int printk_time = 0;
#endif
+ module_param(printk_time, int, S_IRUGO | S_IWUSR);
static int __init printk_time_setup(char *str)
{
return sched_clock();
}
+ /* Check if we have any console registered that can be called early in boot. */
+ static int have_callable_console(void)
+ {
+ struct console *con;
+
+ for (con = console_drivers; con; con = con->next)
+ if (con->flags & CON_ANYTIME)
+ return 1;
+
+ return 0;
+ }
+
/**
* printk - print a kernel message
* @fmt: format string
log_level_unknown = 1;
}
- if (!cpu_online(smp_processor_id())) {
+ if (!down_trylock(&console_sem)) {
/*
- * Some console drivers may assume that per-cpu resources have
- * been allocated. So don't allow them to be called by this
- * CPU until it is officially up. We shouldn't be calling into
- * random console drivers on a CPU which doesn't exist yet..
+ * We own the drivers. We can drop the spinlock and
+ * let release_console_sem() print the text, maybe ...
*/
+ console_locked = 1;
printk_cpu = UINT_MAX;
spin_unlock_irqrestore(&logbuf_lock, flags);
- goto out;
- }
- if (!down_trylock(&console_sem)) {
- console_locked = 1;
+
/*
- * We own the drivers. We can drop the spinlock and let
- * release_console_sem() print the text
+ * Console drivers may assume that per-cpu resources have
+ * been allocated. So unless they're explicitly marked as
+ * being able to cope (CON_ANYTIME) don't call them until
+ * this CPU is officially up.
*/
- printk_cpu = UINT_MAX;
- spin_unlock_irqrestore(&logbuf_lock, flags);
- console_may_schedule = 0;
- release_console_sem();
+ if (cpu_online(smp_processor_id()) || have_callable_console()) {
+ console_may_schedule = 0;
+ release_console_sem();
+ } else {
+ /* Release by hand to avoid flushing the buffer. */
+ console_locked = 0;
+ up(&console_sem);
+ }
} else {
/*
* Someone else owns the drivers. We drop the spinlock, which
printk_cpu = UINT_MAX;
spin_unlock_irqrestore(&logbuf_lock, flags);
}
- out:
+
preempt_enable();
return printed_len;
}
tty->driver->write(tty, msg, strlen(msg));
return;
}
+EXPORT_SYMBOL_GPL(tty_write_message);
/*
* printk rate limiting, lifted from the networking subsystem.
* most "normal" filesystems (but you don't /have/ to use this:
* the NFS filesystem used to do this differently, for example)
*/
- #include <linux/config.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/compiler.h>
#include <linux/fs.h>
+ #include <linux/uaccess.h>
#include <linux/aio.h>
#include <linux/capability.h>
#include <linux/kernel_stat.h>
*/
#include <linux/buffer_head.h> /* for generic_osync_inode */
- #include <asm/uaccess.h>
#include <asm/mman.h>
static ssize_t
radix_tree_delete(&mapping->page_tree, page->index);
page->mapping = NULL;
mapping->nrpages--;
- pagecache_acct(-1);
+ __dec_zone_page_state(page, NR_FILE_PAGES);
}
void remove_from_page_cache(struct page *page)
}
/**
- * filemap_fdatawrite_range - start writeback against all of a mapping's
- * dirty pages that lie within the byte offsets <start, end>
+ * __filemap_fdatawrite_range - start writeback on mapping dirty pages in range
* @mapping: address space structure to write
* @start: offset in bytes where the range starts
* @end: offset in bytes where the range ends (inclusive)
* @sync_mode: enable synchronous operation
*
+ * Start writeback against all of a mapping's dirty pages that lie
+ * within the byte offsets <start, end> inclusive.
+ *
* If sync_mode is WB_SYNC_ALL then this is a "data integrity" operation, as
- * opposed to a regular memory * cleansing writeback. The difference between
+ * opposed to a regular memory cleansing writeback. The difference between
* these two operations is that if a dirty page/buffer is encountered, it must
* be waited upon, and not just skipped over.
*/
struct writeback_control wbc = {
.sync_mode = sync_mode,
.nr_to_write = mapping->nrpages * 2,
- .start = start,
- .end = end,
+ .range_start = start,
+ .range_end = end,
};
if (!mapping_cap_writeback_dirty(mapping))
static inline int __filemap_fdatawrite(struct address_space *mapping,
int sync_mode)
{
- return __filemap_fdatawrite_range(mapping, 0, 0, sync_mode);
+ return __filemap_fdatawrite_range(mapping, 0, LLONG_MAX, sync_mode);
}
int filemap_fdatawrite(struct address_space *mapping)
return __filemap_fdatawrite_range(mapping, start, end, WB_SYNC_ALL);
}
- /*
+ /**
+ * filemap_flush - mostly a non-blocking flush
+ * @mapping: target address_space
+ *
* This is a mostly non-blocking flush. Not suitable for data-integrity
* purposes - I/O may not be started against all dirty pages.
*/
}
EXPORT_SYMBOL(filemap_flush);
- /*
+ /**
+ * wait_on_page_writeback_range - wait for writeback to complete
+ * @mapping: target address_space
+ * @start: beginning page index
+ * @end: ending page index
+ *
* Wait for writeback to complete against pages indexed by start->end
* inclusive
*/
return ret;
}
- /*
+ /**
+ * sync_page_range - write and wait on all pages in the passed range
+ * @inode: target inode
+ * @mapping: target address_space
+ * @pos: beginning offset in pages to write
+ * @count: number of bytes to write
+ *
* Write and wait upon all the pages in the passed range. This is a "data
* integrity" operation. It waits upon in-flight writeout before starting and
* waiting upon new writeout. If there was an IO error, return it.
}
EXPORT_SYMBOL(sync_page_range);
- /*
+ /**
+ * sync_page_range_nolock
+ * @inode: target inode
+ * @mapping: target address_space
+ * @pos: beginning offset in pages to write
+ * @count: number of bytes to write
+ *
* Note: Holding i_mutex across sync_page_range_nolock is not a good idea
* as it forces O_SYNC writers to different parts of the same file
* to be serialised right until io completion.
EXPORT_SYMBOL(sync_page_range_nolock);
/**
- * filemap_fdatawait - walk the list of under-writeback pages of the given
- * address space and wait for all of them.
- *
+ * filemap_fdatawait - wait for all under-writeback pages to complete
* @mapping: address space structure to wait for
+ *
+ * Walk the list of under-writeback pages of the given address space
+ * and wait for all of them.
*/
int filemap_fdatawait(struct address_space *mapping)
{
}
EXPORT_SYMBOL(filemap_write_and_wait);
- /*
+ /**
+ * filemap_write_and_wait_range - write out & wait on a file range
+ * @mapping: the address_space for the pages
+ * @lstart: offset in bytes where the range starts
+ * @lend: offset in bytes where the range ends (inclusive)
+ *
* Write out and wait upon file offsets lstart->lend, inclusive.
*
* Note that `lend' is inclusive (describes the last byte to be written) so
return err;
}
- /*
- * This function is used to add newly allocated pagecache pages:
+ /**
+ * add_to_page_cache - add newly allocated pagecache pages
+ * @page: page to add
+ * @mapping: the page's address_space
+ * @offset: page index
+ * @gfp_mask: page allocation mode
+ *
+ * This function is used to add newly allocated pagecache pages;
* the page is new, so we can just run SetPageLocked() against it.
* The other page state flags were set by rmqueue().
*
page->mapping = mapping;
page->index = offset;
mapping->nrpages++;
- pagecache_acct(1);
+ __inc_zone_page_state(page, NR_FILE_PAGES);
}
write_unlock_irq(&mapping->tree_lock);
radix_tree_preload_end();
}
return error;
}
-
EXPORT_SYMBOL(add_to_page_cache);
int add_to_page_cache_lru(struct page *page, struct address_space *mapping,
EXPORT_SYMBOL(wait_on_page_bit);
/**
- * unlock_page() - unlock a locked page
- *
+ * unlock_page - unlock a locked page
* @page: the page
*
* Unlocks the page and wakes up sleepers in ___wait_on_page_locked().
}
EXPORT_SYMBOL(unlock_page);
- /*
- * End writeback against a page.
+ /**
+ * end_page_writeback - end writeback against a page
+ * @page: the page
*/
void end_page_writeback(struct page *page)
{
}
EXPORT_SYMBOL(end_page_writeback);
- /*
- * Get a lock on the page, assuming we need to sleep to get it.
+ /**
+ * __lock_page - get a lock on the page, assuming we need to sleep to get it
+ * @page: the page to lock
*
- * Ugly: running sync_page() in state TASK_UNINTERRUPTIBLE is scary. If some
+ * Ugly. Running sync_page() in state TASK_UNINTERRUPTIBLE is scary. If some
* random driver's requestfn sets TASK_RUNNING, we could busywait. However
* chances are that on the second loop, the block layer's plug list is empty,
* so sync_page() will then return in state TASK_UNINTERRUPTIBLE.
}
EXPORT_SYMBOL(__lock_page);
- /*
- * a rather lightweight function, finding and getting a reference to a
+ /**
+ * find_get_page - find and get a page reference
+ * @mapping: the address_space to search
+ * @offset: the page index
+ *
+ * A rather lightweight function, finding and getting a reference to a
* hashed page atomically.
*/
struct page * find_get_page(struct address_space *mapping, unsigned long offset)
read_unlock_irq(&mapping->tree_lock);
return page;
}
-
EXPORT_SYMBOL(find_get_page);
- /*
- * Same as above, but trylock it instead of incrementing the count.
+ /**
+ * find_trylock_page - find and lock a page
+ * @mapping: the address_space to search
+ * @offset: the page index
+ *
+ * Same as find_get_page(), but trylock it instead of incrementing the count.
*/
struct page *find_trylock_page(struct address_space *mapping, unsigned long offset)
{
read_unlock_irq(&mapping->tree_lock);
return page;
}
-
EXPORT_SYMBOL(find_trylock_page);
/**
* find_lock_page - locate, pin and lock a pagecache page
- *
* @mapping: the address_space to search
* @offset: the page index
*
read_unlock_irq(&mapping->tree_lock);
return page;
}
-
EXPORT_SYMBOL(find_lock_page);
/**
* find_or_create_page - locate or add a pagecache page
- *
* @mapping: the page's address_space
* @index: the page's index into the mapping
* @gfp_mask: page allocation mode
page_cache_release(cached_page);
return page;
}
-
EXPORT_SYMBOL(find_or_create_page);
/**
return i;
}
- /*
+ /**
+ * find_get_pages_tag - find and return pages that match @tag
+ * @mapping: the address_space to search
+ * @index: the starting page index
+ * @tag: the tag index
+ * @nr_pages: the maximum number of pages
+ * @pages: where the resulting pages are placed
+ *
* Like find_get_pages, except we only return pages which are tagged with
- * `tag'. We update *index to index the next page for the traversal.
+ * @tag. We update @index to index the next page for the traversal.
*/
unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index,
int tag, unsigned int nr_pages, struct page **pages)
return ret;
}
- /*
+ /**
+ * grab_cache_page_nowait - returns locked page at given index in given cache
+ * @mapping: target address_space
+ * @index: the page index
+ *
* Same as grab_cache_page, but do not wait if the page is unavailable.
* This is intended for speculative data generators, where the data can
* be regenerated if the page couldn't be grabbed. This routine should
}
return page;
}
EXPORT_SYMBOL(grab_cache_page_nowait);
/*
+ * CD/DVDs are error prone. When a medium error occurs, the driver may fail
+ * a _large_ part of the i/o request. Imagine the worst scenario:
+ *
+ * ---R__________________________________________B__________
+ * ^ reading here ^ bad block(assume 4k)
+ *
+ * read(R) => miss => readahead(R...B) => media error => frustrating retries
+ * => failing the whole request => read(R) => read(R+1) =>
+ * readahead(R+1...B+1) => bang => read(R+2) => read(R+3) =>
+ * readahead(R+3...B+2) => bang => read(R+3) => read(R+4) =>
+ * readahead(R+4...B+3) => bang => read(R+4) => read(R+5) => ......
+ *
+ * It is going insane. Fix it by quickly scaling down the readahead size.
+ */
+ static void shrink_readahead_size_eio(struct file *filp,
+ struct file_ra_state *ra)
+ {
+ if (!ra->ra_pages)
+ return;
+
+ ra->ra_pages /= 4;
+ printk(KERN_WARNING "Reducing readahead size to %luK\n",
+ ra->ra_pages << (PAGE_CACHE_SHIFT - 10));
+ }
+
+ /**
+ * do_generic_mapping_read - generic file read routine
+ * @mapping: address_space to be read
+ * @_ra: file's readahead state
+ * @filp: the file to read
+ * @ppos: current file position
+ * @desc: read_descriptor
+ * @actor: read method
+ *
* This is a generic file read routine, and uses the
- * mapping->a_ops->readpage() function for the actual low-level
- * stuff.
+ * mapping->a_ops->readpage() function for the actual low-level stuff.
*
* This is really ugly. But the goto's actually try to clarify some
* of the logic when it comes to error handling etc.
*
- * Note the struct file* is only passed for the use of readpage. It may be
- * NULL.
+ * Note the struct file* is only passed for the use of readpage.
+ * It may be NULL.
*/
void do_generic_mapping_read(struct address_space *mapping,
struct file_ra_state *_ra,
}
unlock_page(page);
error = -EIO;
+ shrink_readahead_size_eio(filp, &ra);
goto readpage_error;
}
unlock_page(page);
if (filp)
file_accessed(filp);
}
-
EXPORT_SYMBOL(do_generic_mapping_read);
int file_read_actor(read_descriptor_t *desc, struct page *page,
desc->arg.buf += size;
return size;
}
+EXPORT_SYMBOL_GPL(file_read_actor);
- /*
+ /**
+ * __generic_file_aio_read - generic filesystem read routine
+ * @iocb: kernel I/O control block
+ * @iov: io vector request
+ * @nr_segs: number of segments in the iovec
+ * @ppos: current file position
+ *
* This is the "read()" routine for all filesystems
* that can use the page cache directly.
*/
out:
return retval;
}
-
EXPORT_SYMBOL(__generic_file_aio_read);
ssize_t
BUG_ON(iocb->ki_pos != pos);
return __generic_file_aio_read(iocb, &local_iov, 1, &iocb->ki_pos);
}
-
EXPORT_SYMBOL(generic_file_aio_read);
ssize_t
ret = wait_on_sync_kiocb(&kiocb);
return ret;
}
-
EXPORT_SYMBOL(generic_file_read);
int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned long offset, unsigned long size)
return desc.written;
return desc.error;
}
-
EXPORT_SYMBOL(generic_file_sendfile);
static ssize_t
}
#ifdef CONFIG_MMU
- /*
+ static int FASTCALL(page_cache_read(struct file * file, unsigned long offset));
+ /**
+ * page_cache_read - adds requested page to the page cache if not already there
+ * @file: file to read
+ * @offset: page index
+ *
* This adds the requested page to the page cache if it isn't already there,
* and schedules an I/O to read in its contents from disk.
*/
- static int FASTCALL(page_cache_read(struct file * file, unsigned long offset));
static int fastcall page_cache_read(struct file * file, unsigned long offset)
{
struct address_space *mapping = file->f_mapping;
#define MMAP_LOTSAMISS (100)
- /*
+ /**
+ * filemap_nopage - read in file data for page fault handling
+ * @area: the applicable vm_area
+ * @address: target address to read in
+ * @type: returned with VM_FAULT_{MINOR,MAJOR} if not %NULL
+ *
* filemap_nopage() is invoked via the vma operations vector for a
* mapped memory region to read in file data during a page fault.
*
*/
if (!did_readaround) {
majmin = VM_FAULT_MAJOR;
- inc_page_state(pgmajfault);
+ count_vm_event(PGMAJFAULT);
}
did_readaround = 1;
ra_pages = max_sane_readahead(file->f_ra.ra_pages);
page_not_uptodate:
if (!did_readaround) {
majmin = VM_FAULT_MAJOR;
- inc_page_state(pgmajfault);
+ count_vm_event(PGMAJFAULT);
}
lock_page(page);
* Things didn't work out. Return zero to tell the
* mm layer so, possibly freeing the page cache page first.
*/
+ shrink_readahead_size_eio(file, ra);
page_cache_release(page);
return NULL;
}
-
EXPORT_SYMBOL(filemap_nopage);
static struct page * filemap_getpage(struct file *file, unsigned long pgoff,
return page;
}
- /*
+ /**
+ * read_cache_page - read into page cache, fill it if needed
+ * @mapping: the page's address_space
+ * @index: the page index
+ * @filler: function to perform the read
+ * @data: destination for read data
+ *
* Read into the page cache. If a page already exists,
* and PageUptodate() is not set, try to fill the page.
*/
out:
return page;
}
-
EXPORT_SYMBOL(read_cache_page);
/*
EXPORT_SYMBOL(remove_suid);
size_t
- __filemap_copy_from_user_iovec(char *vaddr,
+ __filemap_copy_from_user_iovec_inatomic(char *vaddr,
const struct iovec *iov, size_t base, size_t bytes)
{
size_t copied = 0, left = 0;
int copy = min(bytes, iov->iov_len - base);
base = 0;
- left = __copy_from_user_inatomic(vaddr, buf, copy);
+ left = __copy_from_user_inatomic_nocache(vaddr, buf, copy);
copied += copy;
bytes -= copy;
vaddr += copy;
iov++;
- if (unlikely(left)) {
- /* zero the rest of the target like __copy_from_user */
- if (bytes)
- memset(vaddr, 0, bytes);
+ if (unlikely(left))
break;
- }
}
return copied - left;
}
/*
* Performs necessary checks before doing a write
*
- * Can adjust writing position aor amount of bytes to write.
+ * Can adjust writing position or amount of bytes to write.
* Returns appropriate error code that caller should return or
* zero in case that write should be allowed.
*/
{
struct file *file = iocb->ki_filp;
struct address_space * mapping = file->f_mapping;
- struct address_space_operations *a_ops = mapping->a_ops;
+ const struct address_space_operations *a_ops = mapping->a_ops;
struct inode *inode = mapping->host;
long status = 0;
struct page *page;
do {
unsigned long index;
unsigned long offset;
- unsigned long maxlen;
size_t copied;
offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
index = pos >> PAGE_CACHE_SHIFT;
bytes = PAGE_CACHE_SIZE - offset;
- if (bytes > count)
- bytes = count;
+
+ /* Limit the size of the copy to the caller's write size */
+ bytes = min(bytes, count);
+
+ /*
+ * Limit the size of the copy to that of the current segment,
+ * because fault_in_pages_readable() doesn't know how to walk
+ * segments.
+ */
+ bytes = min(bytes, cur_iov->iov_len - iov_base);
/*
* Bring in the user page that we will copy from _first_.
* same page as we're writing to, without it being marked
* up-to-date.
*/
- maxlen = cur_iov->iov_len - iov_base;
- if (maxlen > bytes)
- maxlen = bytes;
- fault_in_pages_readable(buf, maxlen);
+ fault_in_pages_readable(buf, bytes);
page = __grab_cache_page(mapping,index,&cached_page,&lru_pvec);
if (!page) {
break;
}
+ if (unlikely(bytes == 0)) {
+ status = 0;
+ copied = 0;
+ goto zero_length_segment;
+ }
+
status = a_ops->prepare_write(file, page, offset, offset+bytes);
if (unlikely(status)) {
loff_t isize = i_size_read(inode);
page_cache_release(page);
continue;
}
- if (likely(copied > 0)) {
+ zero_length_segment:
+ if (likely(copied >= 0)) {
if (!status)
status = copied;
unsigned long nr_segs, loff_t *ppos)
{
struct file *file = iocb->ki_filp;
- struct address_space * mapping = file->f_mapping;
+ const struct address_space * mapping = file->f_mapping;
size_t ocount; /* original count */
size_t count; /* after file limit checks */
struct inode *inode = mapping->host;
ra->ra_pages = mapping->backing_dev_info->ra_pages;
ra->prev_page = -1;
}
+EXPORT_SYMBOL_GPL(file_ra_state_init);
/*
* Return max readahead size for this inode in number-of-pages.
#define list_to_page(head) (list_entry((head)->prev, struct page, lru))
/**
- * read_cache_pages - populate an address space with some pages, and
- * start reads against them.
+ * read_cache_pages - populate an address space with some pages & start reads against them
* @mapping: the address_space
* @pages: The address of a list_head which contains the target pages. These
* pages have their ->index populated and are otherwise uninitialised.
list_del(&page->lru);
if (!add_to_page_cache(page, mapping,
page->index, GFP_KERNEL)) {
- ret = mapping->a_ops->readpage(filp, page);
- if (ret != AOP_TRUNCATED_PAGE) {
- if (!pagevec_add(&lru_pvec, page))
- __pagevec_lru_add(&lru_pvec);
- continue;
- } /* else fall through to release */
- }
- page_cache_release(page);
+ mapping->a_ops->readpage(filp, page);
+ if (!pagevec_add(&lru_pvec, page))
+ __pagevec_lru_add(&lru_pvec);
+ } else
+ page_cache_release(page);
}
pagevec_lru_add(&lru_pvec);
ret = 0;
* Read 'nr_to_read' pages starting at page 'offset'. If the flag 'block'
* is set wait till the read completes. Otherwise attempt to read without
* blocking.
- * Returns 1 meaning 'success' if read is succesfull without switching off
- * readhaead mode. Otherwise return failure.
+ * Returns 1 meaning 'success' if read is successful without switching off
+ * readahead mode. Otherwise return failure.
*/
static int
blockable_page_cache_readahead(struct address_space *mapping, struct file *filp,