aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/9p/conv.c1
-rw-r--r--fs/9p/error.c1
-rw-r--r--fs/9p/fcall.c1
-rw-r--r--fs/9p/fcprint.c1
-rw-r--r--fs/9p/fid.c1
-rw-r--r--fs/9p/mux.c3
-rw-r--r--fs/9p/trans_fd.c1
-rw-r--r--fs/9p/v9fs.c1
-rw-r--r--fs/9p/v9fs_vfs.h2
-rw-r--r--fs/9p/vfs_addr.c3
-rw-r--r--fs/9p/vfs_file.c1
-rw-r--r--fs/9p/vfs_inode.c2
-rw-r--r--fs/9p/vfs_super.c1
-rw-r--r--fs/Kconfig14
-rw-r--r--fs/Makefile1
-rw-r--r--fs/adfs/dir.c1
-rw-r--r--fs/adfs/inode.c2
-rw-r--r--fs/affs/affs.h6
-rw-r--r--fs/affs/file.c4
-rw-r--r--fs/affs/symlink.c2
-rw-r--r--fs/afs/file.c2
-rw-r--r--fs/afs/internal.h2
-rw-r--r--fs/befs/linuxvfs.c40
-rw-r--r--fs/bfs/bfs.h2
-rw-r--r--fs/bfs/file.c2
-rw-r--r--fs/binfmt_elf.c17
-rw-r--r--fs/binfmt_elf_fdpic.c980
-rw-r--r--fs/binfmt_flat.c1
-rw-r--r--fs/binfmt_som.c1
-rw-r--r--fs/block_dev.c106
-rw-r--r--fs/buffer.c5
-rw-r--r--fs/char_dev.c2
-rw-r--r--fs/cifs/asn1.c1
-rw-r--r--fs/cifs/cifsfs.h4
-rw-r--r--fs/cifs/file.c6
-rw-r--r--fs/coda/psdev.c23
-rw-r--r--fs/coda/symlink.c2
-rw-r--r--fs/coda/sysctl.c1
-rw-r--r--fs/compat_ioctl.c2
-rw-r--r--fs/configfs/dir.c6
-rw-r--r--fs/configfs/inode.c2
-rw-r--r--fs/configfs/symlink.c2
-rw-r--r--fs/cramfs/inode.c4
-rw-r--r--fs/dcache.c7
-rw-r--r--fs/dcookies.c1
-rw-r--r--fs/debugfs/file.c1
-rw-r--r--fs/debugfs/inode.c1
-rw-r--r--fs/devfs/Makefile8
-rw-r--r--fs/devfs/base.c2836
-rw-r--r--fs/devfs/util.c97
-rw-r--r--fs/direct-io.c6
-rw-r--r--fs/efs/inode.c2
-rw-r--r--fs/efs/symlink.c2
-rw-r--r--fs/eventpoll.c4
-rw-r--r--fs/exec.c1
-rw-r--r--fs/ext2/balloc.c1
-rw-r--r--fs/ext2/ext2.h6
-rw-r--r--fs/ext2/ialloc.c1
-rw-r--r--fs/ext2/inode.c6
-rw-r--r--fs/ext2/super.c3
-rw-r--r--fs/ext2/xattr.h1
-rw-r--r--fs/ext3/acl.h3
-rw-r--r--fs/ext3/balloc.c1
-rw-r--r--fs/ext3/inode.c6
-rw-r--r--fs/ext3/resize.c1
-rw-r--r--fs/ext3/super.c3
-rw-r--r--fs/ext3/xattr.h1
-rw-r--r--fs/fat/inode.c2
-rw-r--r--fs/file.c14
-rw-r--r--fs/file_table.c1
-rw-r--r--fs/freevxfs/vxfs_immed.c2
-rw-r--r--fs/freevxfs/vxfs_inode.c6
-rw-r--r--fs/freevxfs/vxfs_subr.c2
-rw-r--r--fs/fs-writeback.c4
-rw-r--r--fs/fuse/file.c2
-rw-r--r--fs/hfs/hfs_fs.h4
-rw-r--r--fs/hfs/inode.c4
-rw-r--r--fs/hfs/super.c1
-rw-r--r--fs/hfsplus/hfsplus_fs.h4
-rw-r--r--fs/hfsplus/inode.c4
-rw-r--r--fs/hfsplus/super.c1
-rw-r--r--fs/hostfs/hostfs_kern.c6
-rw-r--r--fs/hpfs/file.c2
-rw-r--r--fs/hpfs/hpfs_fn.h4
-rw-r--r--fs/hpfs/namei.c2
-rw-r--r--fs/hugetlbfs/inode.c8
-rw-r--r--fs/inode.c12
-rw-r--r--fs/ioctl.c1
-rw-r--r--fs/ioprio.c29
-rw-r--r--fs/isofs/compress.c3
-rw-r--r--fs/isofs/dir.c1
-rw-r--r--fs/isofs/inode.c3
-rw-r--r--fs/isofs/isofs.h2
-rw-r--r--fs/isofs/rock.c2
-rw-r--r--fs/isofs/zisofs.h2
-rw-r--r--fs/jffs/inode-v23.c4
-rw-r--r--fs/jffs/intrep.c1
-rw-r--r--fs/jffs/jffs_fm.h1
-rw-r--r--fs/jffs2/acl.c6
-rw-r--r--fs/jffs2/acl.h4
-rw-r--r--fs/jffs2/compr_zlib.c1
-rw-r--r--fs/jffs2/debug.h1
-rw-r--r--fs/jffs2/erase.c19
-rw-r--r--fs/jffs2/file.c2
-rw-r--r--fs/jffs2/fs.c3
-rw-r--r--fs/jffs2/gc.c6
-rw-r--r--fs/jffs2/jffs2_fs_sb.h3
-rw-r--r--fs/jffs2/malloc.c4
-rw-r--r--fs/jffs2/nodelist.c3
-rw-r--r--fs/jffs2/nodelist.h3
-rw-r--r--fs/jffs2/nodemgmt.c21
-rw-r--r--fs/jffs2/os-linux.h2
-rw-r--r--fs/jffs2/readinode.c2
-rw-r--r--fs/jffs2/scan.c59
-rw-r--r--fs/jffs2/summary.c41
-rw-r--r--fs/jffs2/super.c1
-rw-r--r--fs/jffs2/xattr.c635
-rw-r--r--fs/jffs2/xattr.h21
-rw-r--r--fs/jfs/inode.c2
-rw-r--r--fs/jfs/jfs_inode.h2
-rw-r--r--fs/jfs/jfs_metapage.c2
-rw-r--r--fs/jfs/jfs_metapage.h2
-rw-r--r--fs/jfs/jfs_txnmgr.c2
-rw-r--r--fs/jfs/super.c1
-rw-r--r--fs/lockd/clntproc.c27
-rw-r--r--fs/lockd/svc.c1
-rw-r--r--fs/lockd/svclock.c1
-rw-r--r--fs/lockd/svcproc.c1
-rw-r--r--fs/lockd/svcsubs.c1
-rw-r--r--fs/lockd/xdr.c1
-rw-r--r--fs/locks.c23
-rw-r--r--fs/minix/inode.c2
-rw-r--r--fs/namei.c20
-rw-r--r--fs/namespace.c1
-rw-r--r--fs/ncpfs/dir.c1
-rw-r--r--fs/ncpfs/inode.c3
-rw-r--r--fs/ncpfs/ioctl.c1
-rw-r--r--fs/ncpfs/mmap.c2
-rw-r--r--fs/ncpfs/ncplib_kernel.c1
-rw-r--r--fs/ncpfs/ncplib_kernel.h1
-rw-r--r--fs/ncpfs/ncpsign_kernel.c1
-rw-r--r--fs/ncpfs/sock.c1
-rw-r--r--fs/ncpfs/symlink.c3
-rw-r--r--fs/nfs/callback.c1
-rw-r--r--fs/nfs/callback_proc.c1
-rw-r--r--fs/nfs/callback_xdr.c1
-rw-r--r--fs/nfs/delegation.c1
-rw-r--r--fs/nfs/dir.c4
-rw-r--r--fs/nfs/direct.c436
-rw-r--r--fs/nfs/file.c2
-rw-r--r--fs/nfs/inode.c1
-rw-r--r--fs/nfs/internal.h4
-rw-r--r--fs/nfs/nfs4proc.c74
-rw-r--r--fs/nfs/nfs4state.c1
-rw-r--r--fs/nfs/pagelist.c2
-rw-r--r--fs/nfs/read.c1
-rw-r--r--fs/nfs/sysctl.c1
-rw-r--r--fs/nfs/write.c30
-rw-r--r--fs/nfsctl.c1
-rw-r--r--fs/nfsd/export.c2
-rw-r--r--fs/nfsd/nfs4callback.c1
-rw-r--r--fs/nfsd/nfs4idmap.c1
-rw-r--r--fs/nfsd/nfs4proc.c8
-rw-r--r--fs/nfsd/nfs4state.c32
-rw-r--r--fs/nfsd/nfsctl.c1
-rw-r--r--fs/nfsd/nfsfh.c27
-rw-r--r--fs/nfsd/nfssvc.c1
-rw-r--r--fs/nfsd/stats.c10
-rw-r--r--fs/nfsd/vfs.c15
-rw-r--r--fs/nls/nls_base.c1
-rw-r--r--fs/ntfs/aops.c4
-rw-r--r--fs/ntfs/inode.c33
-rw-r--r--fs/ntfs/ntfs.h4
-rw-r--r--fs/ntfs/super.c31
-rw-r--r--fs/ntfs/sysctl.h1
-rw-r--r--fs/ocfs2/aops.c11
-rw-r--r--fs/ocfs2/cluster/heartbeat.c20
-rw-r--r--fs/ocfs2/cluster/masklog.h22
-rw-r--r--fs/ocfs2/cluster/ocfs2_heartbeat.h1
-rw-r--r--fs/ocfs2/cluster/tcp.c14
-rw-r--r--fs/ocfs2/dir.c6
-rw-r--r--fs/ocfs2/dlm/dlmcommon.h2
-rw-r--r--fs/ocfs2/dlm/dlmdomain.c9
-rw-r--r--fs/ocfs2/dlm/dlmrecovery.c8
-rw-r--r--fs/ocfs2/dlmglue.c3
-rw-r--r--fs/ocfs2/extent_map.c29
-rw-r--r--fs/ocfs2/inode.h2
-rw-r--r--fs/ocfs2/journal.c5
-rw-r--r--fs/ocfs2/mmap.c4
-rw-r--r--fs/ocfs2/ocfs2.h4
-rw-r--r--fs/ocfs2/slot_map.c2
-rw-r--r--fs/ocfs2/super.c49
-rw-r--r--fs/ocfs2/symlink.c2
-rw-r--r--fs/partitions/Makefile1
-rw-r--r--fs/partitions/acorn.c1
-rw-r--r--fs/partitions/check.c33
-rw-r--r--fs/partitions/devfs.c130
-rw-r--r--fs/partitions/devfs.h10
-rw-r--r--fs/partitions/efi.c1
-rw-r--r--fs/partitions/efi.h1
-rw-r--r--fs/partitions/ibm.c1
-rw-r--r--fs/partitions/mac.c1
-rw-r--r--fs/partitions/msdos.c1
-rw-r--r--fs/proc/array.c1
-rw-r--r--fs/proc/base.c1
-rw-r--r--fs/proc/kcore.c5
-rw-r--r--fs/proc/proc_misc.c24
-rw-r--r--fs/proc/root.c1
-rw-r--r--fs/proc/task_nommu.c2
-rw-r--r--fs/proc/vmcore.c1
-rw-r--r--fs/qnx4/bitmap.c1
-rw-r--r--fs/qnx4/dir.c1
-rw-r--r--fs/qnx4/fsync.c1
-rw-r--r--fs/qnx4/inode.c3
-rw-r--r--fs/qnx4/namei.c1
-rw-r--r--fs/qnx4/truncate.c1
-rw-r--r--fs/ramfs/file-mmu.c2
-rw-r--r--fs/ramfs/file-nommu.c6
-rw-r--r--fs/ramfs/internal.h2
-rw-r--r--fs/read_write.c2
-rw-r--r--fs/reiserfs/bitmap.c1
-rw-r--r--fs/reiserfs/dir.c1
-rw-r--r--fs/reiserfs/do_balan.c1
-rw-r--r--fs/reiserfs/file.c6
-rw-r--r--fs/reiserfs/fix_node.c1
-rw-r--r--fs/reiserfs/ibalance.c1
-rw-r--r--fs/reiserfs/inode.c8
-rw-r--r--fs/reiserfs/journal.c1
-rw-r--r--fs/reiserfs/lbalance.c1
-rw-r--r--fs/reiserfs/namei.c1
-rw-r--r--fs/reiserfs/objectid.c1
-rw-r--r--fs/reiserfs/prints.c1
-rw-r--r--fs/reiserfs/procfs.c1
-rw-r--r--fs/reiserfs/stree.c1
-rw-r--r--fs/reiserfs/super.c3
-rw-r--r--fs/reiserfs/tail_conversion.c1
-rw-r--r--fs/romfs/inode.c2
-rw-r--r--fs/smbfs/file.c2
-rw-r--r--fs/smbfs/inode.c1
-rw-r--r--fs/smbfs/proto.h2
-rw-r--r--fs/smbfs/smbiod.c1
-rw-r--r--fs/splice.c238
-rw-r--r--fs/stat.c1
-rw-r--r--fs/super.c12
-rw-r--r--fs/sysfs/inode.c14
-rw-r--r--fs/sysv/itree.c2
-rw-r--r--fs/sysv/sysv.h2
-rw-r--r--fs/udf/file.c2
-rw-r--r--fs/udf/inode.c2
-rw-r--r--fs/udf/super.c1
-rw-r--r--fs/udf/symlink.c2
-rw-r--r--fs/udf/udfdecl.h7
-rw-r--r--fs/ufs/balloc.c48
-rw-r--r--fs/ufs/file.c4
-rw-r--r--fs/ufs/inode.c15
-rw-r--r--fs/ufs/super.c3
-rw-r--r--fs/ufs/truncate.c148
-rw-r--r--fs/ufs/util.c54
-rw-r--r--fs/ufs/util.h8
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c2
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.h2
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.c2
-rw-r--r--fs/xfs/linux-2.6/xfs_buf.h1
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl32.c1
-rw-r--r--fs/xfs/linux-2.6/xfs_iops.c9
-rw-r--r--fs/xfs/linux-2.6/xfs_linux.h4
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h2
-rw-r--r--fs/xfs/xfs_behavior.h3
-rw-r--r--fs/xfs/xfs_inode.c4
-rw-r--r--fs/xfs/xfs_log.c4
-rw-r--r--fs/xfs/xfs_log_recover.c2
-rw-r--r--fs/xfs/xfs_mount.c3
-rw-r--r--fs/xfs/xfs_rtalloc.c2
-rw-r--r--fs/xfs/xfs_trans.h4
-rw-r--r--fs/xfs/xfs_vnodeops.c11
275 files changed, 2567 insertions, 4586 deletions
diff --git a/fs/9p/conv.c b/fs/9p/conv.c
index a767e05b60bf..1e898144eb7c 100644
--- a/fs/9p/conv.c
+++ b/fs/9p/conv.c
@@ -24,7 +24,6 @@
24 * 24 *
25 */ 25 */
26 26
27#include <linux/config.h>
28#include <linux/module.h> 27#include <linux/module.h>
29#include <linux/errno.h> 28#include <linux/errno.h>
30#include <linux/fs.h> 29#include <linux/fs.h>
diff --git a/fs/9p/error.c b/fs/9p/error.c
index 981fe8ecd780..ae91555c1558 100644
--- a/fs/9p/error.c
+++ b/fs/9p/error.c
@@ -27,7 +27,6 @@
27 * 27 *
28 */ 28 */
29 29
30#include <linux/config.h>
31#include <linux/module.h> 30#include <linux/module.h>
32 31
33#include <linux/list.h> 32#include <linux/list.h>
diff --git a/fs/9p/fcall.c b/fs/9p/fcall.c
index 6f2617820a4e..8556097fcda8 100644
--- a/fs/9p/fcall.c
+++ b/fs/9p/fcall.c
@@ -24,7 +24,6 @@
24 * 24 *
25 */ 25 */
26 26
27#include <linux/config.h>
28#include <linux/module.h> 27#include <linux/module.h>
29#include <linux/errno.h> 28#include <linux/errno.h>
30#include <linux/fs.h> 29#include <linux/fs.h>
diff --git a/fs/9p/fcprint.c b/fs/9p/fcprint.c
index 583e827baebd..34b96114a28d 100644
--- a/fs/9p/fcprint.c
+++ b/fs/9p/fcprint.c
@@ -21,7 +21,6 @@
21 * Boston, MA 02111-1301 USA 21 * Boston, MA 02111-1301 USA
22 * 22 *
23 */ 23 */
24#include <linux/config.h>
25#include <linux/module.h> 24#include <linux/module.h>
26#include <linux/errno.h> 25#include <linux/errno.h>
27#include <linux/fs.h> 26#include <linux/fs.h>
diff --git a/fs/9p/fid.c b/fs/9p/fid.c
index b7608af07ce8..70492ccb4385 100644
--- a/fs/9p/fid.c
+++ b/fs/9p/fid.c
@@ -20,7 +20,6 @@
20 * 20 *
21 */ 21 */
22 22
23#include <linux/config.h>
24#include <linux/module.h> 23#include <linux/module.h>
25#include <linux/errno.h> 24#include <linux/errno.h>
26#include <linux/fs.h> 25#include <linux/fs.h>
diff --git a/fs/9p/mux.c b/fs/9p/mux.c
index 12e1baa4508d..90a79c784549 100644
--- a/fs/9p/mux.c
+++ b/fs/9p/mux.c
@@ -23,7 +23,6 @@
23 * 23 *
24 */ 24 */
25 25
26#include <linux/config.h>
27#include <linux/module.h> 26#include <linux/module.h>
28#include <linux/errno.h> 27#include <linux/errno.h>
29#include <linux/fs.h> 28#include <linux/fs.h>
@@ -932,6 +931,8 @@ v9fs_mux_rpc(struct v9fs_mux_data *m, struct v9fs_fcall *tc,
932 r.rcall || r.err); 931 r.rcall || r.err);
933 } while (!r.rcall && !r.err && err==-ERESTARTSYS && 932 } while (!r.rcall && !r.err && err==-ERESTARTSYS &&
934 m->trans->status==Connected && !m->err); 933 m->trans->status==Connected && !m->err);
934
935 err = -ERESTARTSYS;
935 } 936 }
936 sigpending = 1; 937 sigpending = 1;
937 } 938 }
diff --git a/fs/9p/trans_fd.c b/fs/9p/trans_fd.c
index 94e0a7fd9fc2..34d43355beb7 100644
--- a/fs/9p/trans_fd.c
+++ b/fs/9p/trans_fd.c
@@ -25,7 +25,6 @@
25 * 25 *
26 */ 26 */
27 27
28#include <linux/config.h>
29#include <linux/in.h> 28#include <linux/in.h>
30#include <linux/module.h> 29#include <linux/module.h>
31#include <linux/net.h> 30#include <linux/net.h>
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index d37416eb5791..22f7ccd58d38 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -23,7 +23,6 @@
23 * 23 *
24 */ 24 */
25 25
26#include <linux/config.h>
27#include <linux/module.h> 26#include <linux/module.h>
28#include <linux/errno.h> 27#include <linux/errno.h>
29#include <linux/fs.h> 28#include <linux/fs.h>
diff --git a/fs/9p/v9fs_vfs.h b/fs/9p/v9fs_vfs.h
index f867b8d3e973..450b0c1b385e 100644
--- a/fs/9p/v9fs_vfs.h
+++ b/fs/9p/v9fs_vfs.h
@@ -38,7 +38,7 @@
38 */ 38 */
39 39
40extern struct file_system_type v9fs_fs_type; 40extern struct file_system_type v9fs_fs_type;
41extern struct address_space_operations v9fs_addr_operations; 41extern const struct address_space_operations v9fs_addr_operations;
42extern const struct file_operations v9fs_file_operations; 42extern const struct file_operations v9fs_file_operations;
43extern const struct file_operations v9fs_dir_operations; 43extern const struct file_operations v9fs_dir_operations;
44extern struct dentry_operations v9fs_dentry_operations; 44extern struct dentry_operations v9fs_dentry_operations;
diff --git a/fs/9p/vfs_addr.c b/fs/9p/vfs_addr.c
index efda46fb64d9..9dfd259a70b4 100644
--- a/fs/9p/vfs_addr.c
+++ b/fs/9p/vfs_addr.c
@@ -31,7 +31,6 @@
31#include <linux/string.h> 31#include <linux/string.h>
32#include <linux/smp_lock.h> 32#include <linux/smp_lock.h>
33#include <linux/inet.h> 33#include <linux/inet.h>
34#include <linux/version.h>
35#include <linux/pagemap.h> 34#include <linux/pagemap.h>
36#include <linux/idr.h> 35#include <linux/idr.h>
37 36
@@ -103,6 +102,6 @@ UnmapAndUnlock:
103 return retval; 102 return retval;
104} 103}
105 104
106struct address_space_operations v9fs_addr_operations = { 105const struct address_space_operations v9fs_addr_operations = {
107 .readpage = v9fs_vfs_readpage, 106 .readpage = v9fs_vfs_readpage,
108}; 107};
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index 1a8e46084f0e..c3c47eda7574 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -31,7 +31,6 @@
31#include <linux/string.h> 31#include <linux/string.h>
32#include <linux/smp_lock.h> 32#include <linux/smp_lock.h>
33#include <linux/inet.h> 33#include <linux/inet.h>
34#include <linux/version.h>
35#include <linux/list.h> 34#include <linux/list.h>
36#include <asm/uaccess.h> 35#include <asm/uaccess.h>
37#include <linux/idr.h> 36#include <linux/idr.h>
diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
index 5c6bdf82146c..2f580a197b8d 100644
--- a/fs/9p/vfs_inode.c
+++ b/fs/9p/vfs_inode.c
@@ -300,7 +300,7 @@ clunk_fid:
300 fid = V9FS_NOFID; 300 fid = V9FS_NOFID;
301 301
302put_fid: 302put_fid:
303 if (fid >= 0) 303 if (fid != V9FS_NOFID)
304 v9fs_put_idpool(fid, &v9ses->fidpool); 304 v9fs_put_idpool(fid, &v9ses->fidpool);
305 305
306 kfree(fcall); 306 kfree(fcall);
diff --git a/fs/9p/vfs_super.c b/fs/9p/vfs_super.c
index 8b15bb22caca..63320d4e15d2 100644
--- a/fs/9p/vfs_super.c
+++ b/fs/9p/vfs_super.c
@@ -25,7 +25,6 @@
25 */ 25 */
26 26
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/config.h>
29#include <linux/module.h> 28#include <linux/module.h>
30#include <linux/errno.h> 29#include <linux/errno.h>
31#include <linux/fs.h> 30#include <linux/fs.h>
diff --git a/fs/Kconfig b/fs/Kconfig
index 7db05742a92d..3f00a9faabcb 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -326,7 +326,7 @@ source "fs/xfs/Kconfig"
326 326
327config OCFS2_FS 327config OCFS2_FS
328 tristate "OCFS2 file system support (EXPERIMENTAL)" 328 tristate "OCFS2 file system support (EXPERIMENTAL)"
329 depends on NET && EXPERIMENTAL 329 depends on NET && SYSFS && EXPERIMENTAL
330 select CONFIGFS_FS 330 select CONFIGFS_FS
331 select JBD 331 select JBD
332 select CRC32 332 select CRC32
@@ -356,6 +356,16 @@ config OCFS2_FS
356 - POSIX ACLs 356 - POSIX ACLs
357 - readpages / writepages (not user visible) 357 - readpages / writepages (not user visible)
358 358
359config OCFS2_DEBUG_MASKLOG
360 bool "OCFS2 logging support"
361 depends on OCFS2_FS
362 default y
363 help
364 The ocfs2 filesystem has an extensive logging system. The system
365 allows selection of events to log via files in /sys/o2cb/logmask/.
366 This option will enlarge your kernel, but it allows debugging of
367 ocfs2 filesystem issues.
368
359config MINIX_FS 369config MINIX_FS
360 tristate "Minix fs support" 370 tristate "Minix fs support"
361 help 371 help
@@ -1116,7 +1126,7 @@ config JFFS2_SUMMARY
1116 1126
1117config JFFS2_FS_XATTR 1127config JFFS2_FS_XATTR
1118 bool "JFFS2 XATTR support (EXPERIMENTAL)" 1128 bool "JFFS2 XATTR support (EXPERIMENTAL)"
1119 depends on JFFS2_FS && EXPERIMENTAL && !JFFS2_FS_WRITEBUFFER 1129 depends on JFFS2_FS && EXPERIMENTAL
1120 default n 1130 default n
1121 help 1131 help
1122 Extended attributes are name:value pairs associated with inodes by 1132 Extended attributes are name:value pairs associated with inodes by
diff --git a/fs/Makefile b/fs/Makefile
index d0ea6bfccf29..89135428a539 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -66,7 +66,6 @@ obj-$(CONFIG_MSDOS_FS) += msdos/
66obj-$(CONFIG_VFAT_FS) += vfat/ 66obj-$(CONFIG_VFAT_FS) += vfat/
67obj-$(CONFIG_BFS_FS) += bfs/ 67obj-$(CONFIG_BFS_FS) += bfs/
68obj-$(CONFIG_ISO9660_FS) += isofs/ 68obj-$(CONFIG_ISO9660_FS) += isofs/
69obj-$(CONFIG_DEVFS_FS) += devfs/
70obj-$(CONFIG_HFSPLUS_FS) += hfsplus/ # Before hfs to find wrapped HFS+ 69obj-$(CONFIG_HFSPLUS_FS) += hfsplus/ # Before hfs to find wrapped HFS+
71obj-$(CONFIG_HFS_FS) += hfs/ 70obj-$(CONFIG_HFS_FS) += hfs/
72obj-$(CONFIG_VXFS_FS) += freevxfs/ 71obj-$(CONFIG_VXFS_FS) += freevxfs/
diff --git a/fs/adfs/dir.c b/fs/adfs/dir.c
index 7b075fc397da..d3c7905b2ddc 100644
--- a/fs/adfs/dir.c
+++ b/fs/adfs/dir.c
@@ -9,7 +9,6 @@
9 * 9 *
10 * Common directory handling for ADFS 10 * Common directory handling for ADFS
11 */ 11 */
12#include <linux/config.h>
13#include <linux/errno.h> 12#include <linux/errno.h>
14#include <linux/fs.h> 13#include <linux/fs.h>
15#include <linux/adfs_fs.h> 14#include <linux/adfs_fs.h>
diff --git a/fs/adfs/inode.c b/fs/adfs/inode.c
index a02802a30798..534f3eecc985 100644
--- a/fs/adfs/inode.c
+++ b/fs/adfs/inode.c
@@ -72,7 +72,7 @@ static sector_t _adfs_bmap(struct address_space *mapping, sector_t block)
72 return generic_block_bmap(mapping, block, adfs_get_block); 72 return generic_block_bmap(mapping, block, adfs_get_block);
73} 73}
74 74
75static struct address_space_operations adfs_aops = { 75static const struct address_space_operations adfs_aops = {
76 .readpage = adfs_readpage, 76 .readpage = adfs_readpage,
77 .writepage = adfs_writepage, 77 .writepage = adfs_writepage,
78 .sync_page = block_sync_page, 78 .sync_page = block_sync_page,
diff --git a/fs/affs/affs.h b/fs/affs/affs.h
index a43a876742b8..0ddd4cc0d1a0 100644
--- a/fs/affs/affs.h
+++ b/fs/affs/affs.h
@@ -195,9 +195,9 @@ extern struct inode_operations affs_symlink_inode_operations;
195extern const struct file_operations affs_file_operations; 195extern const struct file_operations affs_file_operations;
196extern const struct file_operations affs_file_operations_ofs; 196extern const struct file_operations affs_file_operations_ofs;
197extern const struct file_operations affs_dir_operations; 197extern const struct file_operations affs_dir_operations;
198extern struct address_space_operations affs_symlink_aops; 198extern const struct address_space_operations affs_symlink_aops;
199extern struct address_space_operations affs_aops; 199extern const struct address_space_operations affs_aops;
200extern struct address_space_operations affs_aops_ofs; 200extern const struct address_space_operations affs_aops_ofs;
201 201
202extern struct dentry_operations affs_dentry_operations; 202extern struct dentry_operations affs_dentry_operations;
203extern struct dentry_operations affs_dentry_operations_intl; 203extern struct dentry_operations affs_dentry_operations_intl;
diff --git a/fs/affs/file.c b/fs/affs/file.c
index 7076262af39b..3de8590e4f6a 100644
--- a/fs/affs/file.c
+++ b/fs/affs/file.c
@@ -406,7 +406,7 @@ static sector_t _affs_bmap(struct address_space *mapping, sector_t block)
406{ 406{
407 return generic_block_bmap(mapping,block,affs_get_block); 407 return generic_block_bmap(mapping,block,affs_get_block);
408} 408}
409struct address_space_operations affs_aops = { 409const struct address_space_operations affs_aops = {
410 .readpage = affs_readpage, 410 .readpage = affs_readpage,
411 .writepage = affs_writepage, 411 .writepage = affs_writepage,
412 .sync_page = block_sync_page, 412 .sync_page = block_sync_page,
@@ -759,7 +759,7 @@ out:
759 goto done; 759 goto done;
760} 760}
761 761
762struct address_space_operations affs_aops_ofs = { 762const struct address_space_operations affs_aops_ofs = {
763 .readpage = affs_readpage_ofs, 763 .readpage = affs_readpage_ofs,
764 //.writepage = affs_writepage_ofs, 764 //.writepage = affs_writepage_ofs,
765 //.sync_page = affs_sync_page_ofs, 765 //.sync_page = affs_sync_page_ofs,
diff --git a/fs/affs/symlink.c b/fs/affs/symlink.c
index 426f0f094f23..f802256a5933 100644
--- a/fs/affs/symlink.c
+++ b/fs/affs/symlink.c
@@ -66,7 +66,7 @@ fail:
66 return err; 66 return err;
67} 67}
68 68
69struct address_space_operations affs_symlink_aops = { 69const struct address_space_operations affs_symlink_aops = {
70 .readpage = affs_symlink_readpage, 70 .readpage = affs_symlink_readpage,
71}; 71};
72 72
diff --git a/fs/afs/file.c b/fs/afs/file.c
index 7bb716887e29..67d6634101fd 100644
--- a/fs/afs/file.c
+++ b/fs/afs/file.c
@@ -35,7 +35,7 @@ struct inode_operations afs_file_inode_operations = {
35 .getattr = afs_inode_getattr, 35 .getattr = afs_inode_getattr,
36}; 36};
37 37
38struct address_space_operations afs_fs_aops = { 38const struct address_space_operations afs_fs_aops = {
39 .readpage = afs_file_readpage, 39 .readpage = afs_file_readpage,
40 .sync_page = block_sync_page, 40 .sync_page = block_sync_page,
41 .set_page_dirty = __set_page_dirty_nobuffers, 41 .set_page_dirty = __set_page_dirty_nobuffers,
diff --git a/fs/afs/internal.h b/fs/afs/internal.h
index 72febdf9a35a..e88b3b65ae49 100644
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -69,7 +69,7 @@ extern const struct file_operations afs_dir_file_operations;
69/* 69/*
70 * file.c 70 * file.c
71 */ 71 */
72extern struct address_space_operations afs_fs_aops; 72extern const struct address_space_operations afs_fs_aops;
73extern struct inode_operations afs_file_inode_operations; 73extern struct inode_operations afs_file_inode_operations;
74 74
75#ifdef AFS_CACHING_SUPPORT 75#ifdef AFS_CACHING_SUPPORT
diff --git a/fs/befs/linuxvfs.c b/fs/befs/linuxvfs.c
index 08201fab26cd..fcaeead9696b 100644
--- a/fs/befs/linuxvfs.c
+++ b/fs/befs/linuxvfs.c
@@ -73,7 +73,7 @@ static struct inode_operations befs_dir_inode_operations = {
73 .lookup = befs_lookup, 73 .lookup = befs_lookup,
74}; 74};
75 75
76static struct address_space_operations befs_aops = { 76static const struct address_space_operations befs_aops = {
77 .readpage = befs_readpage, 77 .readpage = befs_readpage,
78 .sync_page = block_sync_page, 78 .sync_page = block_sync_page,
79 .bmap = befs_bmap, 79 .bmap = befs_bmap,
@@ -325,7 +325,7 @@ befs_read_inode(struct inode *inode)
325 if (!bh) { 325 if (!bh) {
326 befs_error(sb, "unable to read inode block - " 326 befs_error(sb, "unable to read inode block - "
327 "inode = %lu", inode->i_ino); 327 "inode = %lu", inode->i_ino);
328 goto unaquire_none; 328 goto unacquire_none;
329 } 329 }
330 330
331 raw_inode = (befs_inode *) bh->b_data; 331 raw_inode = (befs_inode *) bh->b_data;
@@ -334,7 +334,7 @@ befs_read_inode(struct inode *inode)
334 334
335 if (befs_check_inode(sb, raw_inode, inode->i_ino) != BEFS_OK) { 335 if (befs_check_inode(sb, raw_inode, inode->i_ino) != BEFS_OK) {
336 befs_error(sb, "Bad inode: %lu", inode->i_ino); 336 befs_error(sb, "Bad inode: %lu", inode->i_ino);
337 goto unaquire_bh; 337 goto unacquire_bh;
338 } 338 }
339 339
340 inode->i_mode = (umode_t) fs32_to_cpu(sb, raw_inode->mode); 340 inode->i_mode = (umode_t) fs32_to_cpu(sb, raw_inode->mode);
@@ -402,17 +402,17 @@ befs_read_inode(struct inode *inode)
402 befs_error(sb, "Inode %lu is not a regular file, " 402 befs_error(sb, "Inode %lu is not a regular file, "
403 "directory or symlink. THAT IS WRONG! BeFS has no " 403 "directory or symlink. THAT IS WRONG! BeFS has no "
404 "on disk special files", inode->i_ino); 404 "on disk special files", inode->i_ino);
405 goto unaquire_bh; 405 goto unacquire_bh;
406 } 406 }
407 407
408 brelse(bh); 408 brelse(bh);
409 befs_debug(sb, "<--- befs_read_inode()"); 409 befs_debug(sb, "<--- befs_read_inode()");
410 return; 410 return;
411 411
412 unaquire_bh: 412 unacquire_bh:
413 brelse(bh); 413 brelse(bh);
414 414
415 unaquire_none: 415 unacquire_none:
416 make_bad_inode(inode); 416 make_bad_inode(inode);
417 befs_debug(sb, "<--- befs_read_inode() - Bad inode"); 417 befs_debug(sb, "<--- befs_read_inode() - Bad inode");
418 return; 418 return;
@@ -761,14 +761,14 @@ befs_fill_super(struct super_block *sb, void *data, int silent)
761 printk(KERN_ERR 761 printk(KERN_ERR
762 "BeFS(%s): Unable to allocate memory for private " 762 "BeFS(%s): Unable to allocate memory for private "
763 "portion of superblock. Bailing.\n", sb->s_id); 763 "portion of superblock. Bailing.\n", sb->s_id);
764 goto unaquire_none; 764 goto unacquire_none;
765 } 765 }
766 befs_sb = BEFS_SB(sb); 766 befs_sb = BEFS_SB(sb);
767 memset(befs_sb, 0, sizeof(befs_sb_info)); 767 memset(befs_sb, 0, sizeof(befs_sb_info));
768 768
769 if (!parse_options((char *) data, &befs_sb->mount_opts)) { 769 if (!parse_options((char *) data, &befs_sb->mount_opts)) {
770 befs_error(sb, "cannot parse mount options"); 770 befs_error(sb, "cannot parse mount options");
771 goto unaquire_priv_sbp; 771 goto unacquire_priv_sbp;
772 } 772 }
773 773
774 befs_debug(sb, "---> befs_fill_super()"); 774 befs_debug(sb, "---> befs_fill_super()");
@@ -794,7 +794,7 @@ befs_fill_super(struct super_block *sb, void *data, int silent)
794 794
795 if (!(bh = sb_bread(sb, sb_block))) { 795 if (!(bh = sb_bread(sb, sb_block))) {
796 befs_error(sb, "unable to read superblock"); 796 befs_error(sb, "unable to read superblock");
797 goto unaquire_priv_sbp; 797 goto unacquire_priv_sbp;
798 } 798 }
799 799
800 /* account for offset of super block on x86 */ 800 /* account for offset of super block on x86 */
@@ -809,20 +809,20 @@ befs_fill_super(struct super_block *sb, void *data, int silent)
809 } 809 }
810 810
811 if (befs_load_sb(sb, disk_sb) != BEFS_OK) 811 if (befs_load_sb(sb, disk_sb) != BEFS_OK)
812 goto unaquire_bh; 812 goto unacquire_bh;
813 813
814 befs_dump_super_block(sb, disk_sb); 814 befs_dump_super_block(sb, disk_sb);
815 815
816 brelse(bh); 816 brelse(bh);
817 817
818 if (befs_check_sb(sb) != BEFS_OK) 818 if (befs_check_sb(sb) != BEFS_OK)
819 goto unaquire_priv_sbp; 819 goto unacquire_priv_sbp;
820 820
821 if( befs_sb->num_blocks > ~((sector_t)0) ) { 821 if( befs_sb->num_blocks > ~((sector_t)0) ) {
822 befs_error(sb, "blocks count: %Lu " 822 befs_error(sb, "blocks count: %Lu "
823 "is larger than the host can use", 823 "is larger than the host can use",
824 befs_sb->num_blocks); 824 befs_sb->num_blocks);
825 goto unaquire_priv_sbp; 825 goto unacquire_priv_sbp;
826 } 826 }
827 827
828 /* 828 /*
@@ -838,7 +838,7 @@ befs_fill_super(struct super_block *sb, void *data, int silent)
838 if (!sb->s_root) { 838 if (!sb->s_root) {
839 iput(root); 839 iput(root);
840 befs_error(sb, "get root inode failed"); 840 befs_error(sb, "get root inode failed");
841 goto unaquire_priv_sbp; 841 goto unacquire_priv_sbp;
842 } 842 }
843 843
844 /* load nls library */ 844 /* load nls library */
@@ -860,13 +860,13 @@ befs_fill_super(struct super_block *sb, void *data, int silent)
860 860
861 return 0; 861 return 0;
862/*****************/ 862/*****************/
863 unaquire_bh: 863 unacquire_bh:
864 brelse(bh); 864 brelse(bh);
865 865
866 unaquire_priv_sbp: 866 unacquire_priv_sbp:
867 kfree(sb->s_fs_info); 867 kfree(sb->s_fs_info);
868 868
869 unaquire_none: 869 unacquire_none:
870 sb->s_fs_info = NULL; 870 sb->s_fs_info = NULL;
871 return -EINVAL; 871 return -EINVAL;
872} 872}
@@ -925,18 +925,18 @@ init_befs_fs(void)
925 925
926 err = befs_init_inodecache(); 926 err = befs_init_inodecache();
927 if (err) 927 if (err)
928 goto unaquire_none; 928 goto unacquire_none;
929 929
930 err = register_filesystem(&befs_fs_type); 930 err = register_filesystem(&befs_fs_type);
931 if (err) 931 if (err)
932 goto unaquire_inodecache; 932 goto unacquire_inodecache;
933 933
934 return 0; 934 return 0;
935 935
936unaquire_inodecache: 936unacquire_inodecache:
937 befs_destroy_inodecache(); 937 befs_destroy_inodecache();
938 938
939unaquire_none: 939unacquire_none:
940 return err; 940 return err;
941} 941}
942 942
diff --git a/fs/bfs/bfs.h b/fs/bfs/bfs.h
index 9d791004b21c..31973bbbf057 100644
--- a/fs/bfs/bfs.h
+++ b/fs/bfs/bfs.h
@@ -50,7 +50,7 @@ static inline struct bfs_inode_info *BFS_I(struct inode *inode)
50/* file.c */ 50/* file.c */
51extern struct inode_operations bfs_file_inops; 51extern struct inode_operations bfs_file_inops;
52extern const struct file_operations bfs_file_operations; 52extern const struct file_operations bfs_file_operations;
53extern struct address_space_operations bfs_aops; 53extern const struct address_space_operations bfs_aops;
54 54
55/* dir.c */ 55/* dir.c */
56extern struct inode_operations bfs_dir_inops; 56extern struct inode_operations bfs_dir_inops;
diff --git a/fs/bfs/file.c b/fs/bfs/file.c
index d83cd74a2e4e..3d5aca28a0a0 100644
--- a/fs/bfs/file.c
+++ b/fs/bfs/file.c
@@ -153,7 +153,7 @@ static sector_t bfs_bmap(struct address_space *mapping, sector_t block)
153 return generic_block_bmap(mapping, block, bfs_get_block); 153 return generic_block_bmap(mapping, block, bfs_get_block);
154} 154}
155 155
156struct address_space_operations bfs_aops = { 156const struct address_space_operations bfs_aops = {
157 .readpage = bfs_readpage, 157 .readpage = bfs_readpage,
158 .writepage = bfs_writepage, 158 .writepage = bfs_writepage,
159 .sync_page = block_sync_page, 159 .sync_page = block_sync_page,
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index d0434406eaeb..672a3b90bc55 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -84,7 +84,7 @@ static struct linux_binfmt elf_format = {
84 .min_coredump = ELF_EXEC_PAGESIZE 84 .min_coredump = ELF_EXEC_PAGESIZE
85}; 85};
86 86
87#define BAD_ADDR(x) ((unsigned long)(x) > TASK_SIZE) 87#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE)
88 88
89static int set_brk(unsigned long start, unsigned long end) 89static int set_brk(unsigned long start, unsigned long end)
90{ 90{
@@ -394,7 +394,7 @@ static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
394 * <= p_memsize so it's only necessary to check p_memsz. 394 * <= p_memsize so it's only necessary to check p_memsz.
395 */ 395 */
396 k = load_addr + eppnt->p_vaddr; 396 k = load_addr + eppnt->p_vaddr;
397 if (k > TASK_SIZE || 397 if (BAD_ADDR(k) ||
398 eppnt->p_filesz > eppnt->p_memsz || 398 eppnt->p_filesz > eppnt->p_memsz ||
399 eppnt->p_memsz > TASK_SIZE || 399 eppnt->p_memsz > TASK_SIZE ||
400 TASK_SIZE - eppnt->p_memsz < k) { 400 TASK_SIZE - eppnt->p_memsz < k) {
@@ -887,7 +887,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
887 * allowed task size. Note that p_filesz must always be 887 * allowed task size. Note that p_filesz must always be
888 * <= p_memsz so it is only necessary to check p_memsz. 888 * <= p_memsz so it is only necessary to check p_memsz.
889 */ 889 */
890 if (k > TASK_SIZE || elf_ppnt->p_filesz > elf_ppnt->p_memsz || 890 if (BAD_ADDR(k) || elf_ppnt->p_filesz > elf_ppnt->p_memsz ||
891 elf_ppnt->p_memsz > TASK_SIZE || 891 elf_ppnt->p_memsz > TASK_SIZE ||
892 TASK_SIZE - elf_ppnt->p_memsz < k) { 892 TASK_SIZE - elf_ppnt->p_memsz < k) {
893 /* set_brk can never work. Avoid overflows. */ 893 /* set_brk can never work. Avoid overflows. */
@@ -941,10 +941,9 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
941 interpreter, 941 interpreter,
942 &interp_load_addr); 942 &interp_load_addr);
943 if (BAD_ADDR(elf_entry)) { 943 if (BAD_ADDR(elf_entry)) {
944 printk(KERN_ERR "Unable to load interpreter %.128s\n",
945 elf_interpreter);
946 force_sig(SIGSEGV, current); 944 force_sig(SIGSEGV, current);
947 retval = -ENOEXEC; /* Nobody gets to see this, but.. */ 945 retval = IS_ERR((void *)elf_entry) ?
946 (int)elf_entry : -EINVAL;
948 goto out_free_dentry; 947 goto out_free_dentry;
949 } 948 }
950 reloc_func_desc = interp_load_addr; 949 reloc_func_desc = interp_load_addr;
@@ -955,8 +954,8 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs *regs)
955 } else { 954 } else {
956 elf_entry = loc->elf_ex.e_entry; 955 elf_entry = loc->elf_ex.e_entry;
957 if (BAD_ADDR(elf_entry)) { 956 if (BAD_ADDR(elf_entry)) {
958 send_sig(SIGSEGV, current, 0); 957 force_sig(SIGSEGV, current);
959 retval = -ENOEXEC; /* Nobody gets to see this, but.. */ 958 retval = -EINVAL;
960 goto out_free_dentry; 959 goto out_free_dentry;
961 } 960 }
962 } 961 }
@@ -1186,8 +1185,6 @@ static int maydump(struct vm_area_struct *vma)
1186 return 1; 1185 return 1;
1187} 1186}
1188 1187
1189#define roundup(x, y) ((((x) + ((y) - 1)) / (y)) * (y))
1190
1191/* An ELF note in memory */ 1188/* An ELF note in memory */
1192struct memelfnote 1189struct memelfnote
1193{ 1190{
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index eba4e23b9ca0..2f3365829229 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -1,6 +1,6 @@
1/* binfmt_elf_fdpic.c: FDPIC ELF binary format 1/* binfmt_elf_fdpic.c: FDPIC ELF binary format
2 * 2 *
3 * Copyright (C) 2003, 2004 Red Hat, Inc. All Rights Reserved. 3 * Copyright (C) 2003, 2004, 2006 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com) 4 * Written by David Howells (dhowells@redhat.com)
5 * Derived from binfmt_elf.c 5 * Derived from binfmt_elf.c
6 * 6 *
@@ -24,7 +24,9 @@
24#include <linux/file.h> 24#include <linux/file.h>
25#include <linux/fcntl.h> 25#include <linux/fcntl.h>
26#include <linux/slab.h> 26#include <linux/slab.h>
27#include <linux/pagemap.h>
27#include <linux/highmem.h> 28#include <linux/highmem.h>
29#include <linux/highuid.h>
28#include <linux/personality.h> 30#include <linux/personality.h>
29#include <linux/ptrace.h> 31#include <linux/ptrace.h>
30#include <linux/init.h> 32#include <linux/init.h>
@@ -48,45 +50,59 @@ typedef char *elf_caddr_t;
48#define kdebug(fmt, ...) do {} while(0) 50#define kdebug(fmt, ...) do {} while(0)
49#endif 51#endif
50 52
53#if 0
54#define kdcore(fmt, ...) printk("FDPIC "fmt"\n" ,##__VA_ARGS__ )
55#else
56#define kdcore(fmt, ...) do {} while(0)
57#endif
58
51MODULE_LICENSE("GPL"); 59MODULE_LICENSE("GPL");
52 60
53static int load_elf_fdpic_binary(struct linux_binprm *bprm, struct pt_regs *regs); 61static int load_elf_fdpic_binary(struct linux_binprm *, struct pt_regs *);
54//static int load_elf_fdpic_library(struct file *); 62static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *, struct file *);
55static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *params, struct file *file); 63static int elf_fdpic_map_file(struct elf_fdpic_params *, struct file *,
56static int elf_fdpic_map_file(struct elf_fdpic_params *params, 64 struct mm_struct *, const char *);
57 struct file *file,
58 struct mm_struct *mm,
59 const char *what);
60 65
61static int create_elf_fdpic_tables(struct linux_binprm *bprm, 66static int create_elf_fdpic_tables(struct linux_binprm *, struct mm_struct *,
62 struct mm_struct *mm, 67 struct elf_fdpic_params *,
63 struct elf_fdpic_params *exec_params, 68 struct elf_fdpic_params *);
64 struct elf_fdpic_params *interp_params);
65 69
66#ifndef CONFIG_MMU 70#ifndef CONFIG_MMU
67static int elf_fdpic_transfer_args_to_stack(struct linux_binprm *bprm, unsigned long *_sp); 71static int elf_fdpic_transfer_args_to_stack(struct linux_binprm *,
68static int elf_fdpic_map_file_constdisp_on_uclinux(struct elf_fdpic_params *params, 72 unsigned long *);
69 struct file *file, 73static int elf_fdpic_map_file_constdisp_on_uclinux(struct elf_fdpic_params *,
70 struct mm_struct *mm); 74 struct file *,
75 struct mm_struct *);
71#endif 76#endif
72 77
73static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params, 78static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *,
74 struct file *file, 79 struct file *, struct mm_struct *);
75 struct mm_struct *mm); 80
81#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE)
82static int elf_fdpic_core_dump(long, struct pt_regs *, struct file *);
83#endif
76 84
77static struct linux_binfmt elf_fdpic_format = { 85static struct linux_binfmt elf_fdpic_format = {
78 .module = THIS_MODULE, 86 .module = THIS_MODULE,
79 .load_binary = load_elf_fdpic_binary, 87 .load_binary = load_elf_fdpic_binary,
80// .load_shlib = load_elf_fdpic_library, 88#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE)
81// .core_dump = elf_fdpic_core_dump, 89 .core_dump = elf_fdpic_core_dump,
90#endif
82 .min_coredump = ELF_EXEC_PAGESIZE, 91 .min_coredump = ELF_EXEC_PAGESIZE,
83}; 92};
84 93
85static int __init init_elf_fdpic_binfmt(void) { return register_binfmt(&elf_fdpic_format); } 94static int __init init_elf_fdpic_binfmt(void)
86static void __exit exit_elf_fdpic_binfmt(void) { unregister_binfmt(&elf_fdpic_format); } 95{
96 return register_binfmt(&elf_fdpic_format);
97}
98
99static void __exit exit_elf_fdpic_binfmt(void)
100{
101 unregister_binfmt(&elf_fdpic_format);
102}
87 103
88module_init(init_elf_fdpic_binfmt) 104core_initcall(init_elf_fdpic_binfmt);
89module_exit(exit_elf_fdpic_binfmt) 105module_exit(exit_elf_fdpic_binfmt);
90 106
91static int is_elf_fdpic(struct elfhdr *hdr, struct file *file) 107static int is_elf_fdpic(struct elfhdr *hdr, struct file *file)
92{ 108{
@@ -105,7 +121,8 @@ static int is_elf_fdpic(struct elfhdr *hdr, struct file *file)
105/* 121/*
106 * read the program headers table into memory 122 * read the program headers table into memory
107 */ 123 */
108static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *params, struct file *file) 124static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *params,
125 struct file *file)
109{ 126{
110 struct elf32_phdr *phdr; 127 struct elf32_phdr *phdr;
111 unsigned long size; 128 unsigned long size;
@@ -121,7 +138,8 @@ static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *params, struct file *f
121 if (!params->phdrs) 138 if (!params->phdrs)
122 return -ENOMEM; 139 return -ENOMEM;
123 140
124 retval = kernel_read(file, params->hdr.e_phoff, (char *) params->phdrs, size); 141 retval = kernel_read(file, params->hdr.e_phoff,
142 (char *) params->phdrs, size);
125 if (retval < 0) 143 if (retval < 0)
126 return retval; 144 return retval;
127 145
@@ -141,17 +159,24 @@ static int elf_fdpic_fetch_phdrs(struct elf_fdpic_params *params, struct file *f
141 } 159 }
142 160
143 return 0; 161 return 0;
144} /* end elf_fdpic_fetch_phdrs() */ 162}
145 163
146/*****************************************************************************/ 164/*****************************************************************************/
147/* 165/*
148 * load an fdpic binary into various bits of memory 166 * load an fdpic binary into various bits of memory
149 */ 167 */
150static int load_elf_fdpic_binary(struct linux_binprm *bprm, struct pt_regs *regs) 168static int load_elf_fdpic_binary(struct linux_binprm *bprm,
169 struct pt_regs *regs)
151{ 170{
152 struct elf_fdpic_params exec_params, interp_params; 171 struct elf_fdpic_params exec_params, interp_params;
153 struct elf_phdr *phdr; 172 struct elf_phdr *phdr;
154 unsigned long stack_size; 173 unsigned long stack_size, entryaddr;
174#ifndef CONFIG_MMU
175 unsigned long fullsize;
176#endif
177#ifdef ELF_FDPIC_PLAT_INIT
178 unsigned long dynaddr;
179#endif
155 struct file *interpreter = NULL; /* to shut gcc up */ 180 struct file *interpreter = NULL; /* to shut gcc up */
156 char *interpreter_name = NULL; 181 char *interpreter_name = NULL;
157 int executable_stack; 182 int executable_stack;
@@ -212,7 +237,8 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, struct pt_regs *regs
212 goto error; 237 goto error;
213 } 238 }
214 239
215 retval = kernel_read(interpreter, 0, bprm->buf, BINPRM_BUF_SIZE); 240 retval = kernel_read(interpreter, 0, bprm->buf,
241 BINPRM_BUF_SIZE);
216 if (retval < 0) 242 if (retval < 0)
217 goto error; 243 goto error;
218 244
@@ -295,7 +321,8 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, struct pt_regs *regs
295 &current->mm->start_stack, 321 &current->mm->start_stack,
296 &current->mm->start_brk); 322 &current->mm->start_brk);
297 323
298 retval = setup_arg_pages(bprm, current->mm->start_stack, executable_stack); 324 retval = setup_arg_pages(bprm, current->mm->start_stack,
325 executable_stack);
299 if (retval < 0) { 326 if (retval < 0) {
300 send_sig(SIGKILL, current, 0); 327 send_sig(SIGKILL, current, 0);
301 goto error_kill; 328 goto error_kill;
@@ -303,7 +330,8 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, struct pt_regs *regs
303#endif 330#endif
304 331
305 /* load the executable and interpreter into memory */ 332 /* load the executable and interpreter into memory */
306 retval = elf_fdpic_map_file(&exec_params, bprm->file, current->mm, "executable"); 333 retval = elf_fdpic_map_file(&exec_params, bprm->file, current->mm,
334 "executable");
307 if (retval < 0) 335 if (retval < 0)
308 goto error_kill; 336 goto error_kill;
309 337
@@ -324,7 +352,8 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, struct pt_regs *regs
324 if (!current->mm->start_brk) 352 if (!current->mm->start_brk)
325 current->mm->start_brk = current->mm->end_data; 353 current->mm->start_brk = current->mm->end_data;
326 354
327 current->mm->brk = current->mm->start_brk = PAGE_ALIGN(current->mm->start_brk); 355 current->mm->brk = current->mm->start_brk =
356 PAGE_ALIGN(current->mm->start_brk);
328 357
329#else 358#else
330 /* create a stack and brk area big enough for everyone 359 /* create a stack and brk area big enough for everyone
@@ -336,47 +365,45 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, struct pt_regs *regs
336 stack_size = PAGE_SIZE * 2; 365 stack_size = PAGE_SIZE * 2;
337 366
338 down_write(&current->mm->mmap_sem); 367 down_write(&current->mm->mmap_sem);
339 current->mm->start_brk = do_mmap(NULL, 368 current->mm->start_brk = do_mmap(NULL, 0, stack_size,
340 0,
341 stack_size,
342 PROT_READ | PROT_WRITE | PROT_EXEC, 369 PROT_READ | PROT_WRITE | PROT_EXEC,
343 MAP_PRIVATE | MAP_ANON | MAP_GROWSDOWN, 370 MAP_PRIVATE | MAP_ANON | MAP_GROWSDOWN,
344 0); 371 0);
345 372
346 if (IS_ERR((void *) current->mm->start_brk)) { 373 if (IS_ERR_VALUE(current->mm->start_brk)) {
347 up_write(&current->mm->mmap_sem); 374 up_write(&current->mm->mmap_sem);
348 retval = current->mm->start_brk; 375 retval = current->mm->start_brk;
349 current->mm->start_brk = 0; 376 current->mm->start_brk = 0;
350 goto error_kill; 377 goto error_kill;
351 } 378 }
352 379
353 if (do_mremap(current->mm->start_brk, 380 /* expand the stack mapping to use up the entire allocation granule */
354 stack_size, 381 fullsize = ksize((char *) current->mm->start_brk);
355 ksize((char *) current->mm->start_brk), 382 if (!IS_ERR_VALUE(do_mremap(current->mm->start_brk, stack_size,
356 0, 0 383 fullsize, 0, 0)))
357 ) == current->mm->start_brk 384 stack_size = fullsize;
358 )
359 stack_size = ksize((char *) current->mm->start_brk);
360 up_write(&current->mm->mmap_sem); 385 up_write(&current->mm->mmap_sem);
361 386
362 current->mm->brk = current->mm->start_brk; 387 current->mm->brk = current->mm->start_brk;
363 current->mm->context.end_brk = current->mm->start_brk; 388 current->mm->context.end_brk = current->mm->start_brk;
364 current->mm->context.end_brk += (stack_size > PAGE_SIZE) ? (stack_size - PAGE_SIZE) : 0; 389 current->mm->context.end_brk +=
390 (stack_size > PAGE_SIZE) ? (stack_size - PAGE_SIZE) : 0;
365 current->mm->start_stack = current->mm->start_brk + stack_size; 391 current->mm->start_stack = current->mm->start_brk + stack_size;
366#endif 392#endif
367 393
368 compute_creds(bprm); 394 compute_creds(bprm);
369 current->flags &= ~PF_FORKNOEXEC; 395 current->flags &= ~PF_FORKNOEXEC;
370 if (create_elf_fdpic_tables(bprm, current->mm, &exec_params, &interp_params) < 0) 396 if (create_elf_fdpic_tables(bprm, current->mm,
397 &exec_params, &interp_params) < 0)
371 goto error_kill; 398 goto error_kill;
372 399
373 kdebug("- start_code %lx", (long) current->mm->start_code); 400 kdebug("- start_code %lx", current->mm->start_code);
374 kdebug("- end_code %lx", (long) current->mm->end_code); 401 kdebug("- end_code %lx", current->mm->end_code);
375 kdebug("- start_data %lx", (long) current->mm->start_data); 402 kdebug("- start_data %lx", current->mm->start_data);
376 kdebug("- end_data %lx", (long) current->mm->end_data); 403 kdebug("- end_data %lx", current->mm->end_data);
377 kdebug("- start_brk %lx", (long) current->mm->start_brk); 404 kdebug("- start_brk %lx", current->mm->start_brk);
378 kdebug("- brk %lx", (long) current->mm->brk); 405 kdebug("- brk %lx", current->mm->brk);
379 kdebug("- start_stack %lx", (long) current->mm->start_stack); 406 kdebug("- start_stack %lx", current->mm->start_stack);
380 407
381#ifdef ELF_FDPIC_PLAT_INIT 408#ifdef ELF_FDPIC_PLAT_INIT
382 /* 409 /*
@@ -385,21 +412,18 @@ static int load_elf_fdpic_binary(struct linux_binprm *bprm, struct pt_regs *regs
385 * example. This macro performs whatever initialization to 412 * example. This macro performs whatever initialization to
386 * the regs structure is required. 413 * the regs structure is required.
387 */ 414 */
388 ELF_FDPIC_PLAT_INIT(regs, 415 dynaddr = interp_params.dynamic_addr ?: exec_params.dynamic_addr;
389 exec_params.map_addr, 416 ELF_FDPIC_PLAT_INIT(regs, exec_params.map_addr, interp_params.map_addr,
390 interp_params.map_addr, 417 dynaddr);
391 interp_params.dynamic_addr ?: exec_params.dynamic_addr
392 );
393#endif 418#endif
394 419
395 /* everything is now ready... get the userspace context ready to roll */ 420 /* everything is now ready... get the userspace context ready to roll */
396 start_thread(regs, 421 entryaddr = interp_params.entry_addr ?: exec_params.entry_addr;
397 interp_params.entry_addr ?: exec_params.entry_addr, 422 start_thread(regs, entryaddr, current->mm->start_stack);
398 current->mm->start_stack);
399 423
400 if (unlikely(current->ptrace & PT_PTRACED)) { 424 if (unlikely(current->ptrace & PT_PTRACED)) {
401 if (current->ptrace & PT_TRACE_EXEC) 425 if (current->ptrace & PT_TRACE_EXEC)
402 ptrace_notify ((PTRACE_EVENT_EXEC << 8) | SIGTRAP); 426 ptrace_notify((PTRACE_EVENT_EXEC << 8) | SIGTRAP);
403 else 427 else
404 send_sig(SIGTRAP, current, 0); 428 send_sig(SIGTRAP, current, 0);
405 } 429 }
@@ -419,11 +443,11 @@ error:
419 return retval; 443 return retval;
420 444
421 /* unrecoverable error - kill the process */ 445 /* unrecoverable error - kill the process */
422 error_kill: 446error_kill:
423 send_sig(SIGSEGV, current, 0); 447 send_sig(SIGSEGV, current, 0);
424 goto error; 448 goto error;
425 449
426} /* end load_elf_fdpic_binary() */ 450}
427 451
428/*****************************************************************************/ 452/*****************************************************************************/
429/* 453/*
@@ -459,6 +483,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
459 */ 483 */
460 hwcap = ELF_HWCAP; 484 hwcap = ELF_HWCAP;
461 k_platform = ELF_PLATFORM; 485 k_platform = ELF_PLATFORM;
486 u_platform = NULL;
462 487
463 if (k_platform) { 488 if (k_platform) {
464 platform_len = strlen(k_platform) + 1; 489 platform_len = strlen(k_platform) + 1;
@@ -470,11 +495,11 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
470 495
471#if defined(__i386__) && defined(CONFIG_SMP) 496#if defined(__i386__) && defined(CONFIG_SMP)
472 /* in some cases (e.g. Hyper-Threading), we want to avoid L1 evictions 497 /* in some cases (e.g. Hyper-Threading), we want to avoid L1 evictions
473 * by the processes running on the same package. One thing we can do 498 * by the processes running on the same package. One thing we can do is
474 * is to shuffle the initial stack for them. 499 * to shuffle the initial stack for them.
475 * 500 *
476 * the conditionals here are unneeded, but kept in to make the 501 * the conditionals here are unneeded, but kept in to make the code
477 * code behaviour the same as pre change unless we have hyperthreaded 502 * behaviour the same as pre change unless we have hyperthreaded
478 * processors. This keeps Mr Marcelo Person happier but should be 503 * processors. This keeps Mr Marcelo Person happier but should be
479 * removed for 2.5 504 * removed for 2.5
480 */ 505 */
@@ -497,11 +522,13 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
497 522
498 if (interp_params->loadmap) { 523 if (interp_params->loadmap) {
499 len = sizeof(struct elf32_fdpic_loadmap); 524 len = sizeof(struct elf32_fdpic_loadmap);
500 len += sizeof(struct elf32_fdpic_loadseg) * interp_params->loadmap->nsegs; 525 len += sizeof(struct elf32_fdpic_loadseg) *
526 interp_params->loadmap->nsegs;
501 sp = (sp - len) & ~7UL; 527 sp = (sp - len) & ~7UL;
502 interp_params->map_addr = sp; 528 interp_params->map_addr = sp;
503 529
504 if (copy_to_user((void __user *) sp, interp_params->loadmap, len) != 0) 530 if (copy_to_user((void __user *) sp, interp_params->loadmap,
531 len) != 0)
505 return -EFAULT; 532 return -EFAULT;
506 533
507 current->mm->context.interp_fdpic_loadmap = (unsigned long) sp; 534 current->mm->context.interp_fdpic_loadmap = (unsigned long) sp;
@@ -525,34 +552,37 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
525 sp -= sp & 15UL; 552 sp -= sp & 15UL;
526 553
527 /* put the ELF interpreter info on the stack */ 554 /* put the ELF interpreter info on the stack */
528#define NEW_AUX_ENT(nr, id, val) \ 555#define NEW_AUX_ENT(nr, id, val) \
529 do { \ 556 do { \
530 struct { unsigned long _id, _val; } __user *ent = (void __user *) csp; \ 557 struct { unsigned long _id, _val; } __user *ent; \
531 __put_user((id), &ent[nr]._id); \ 558 \
532 __put_user((val), &ent[nr]._val); \ 559 ent = (void __user *) csp; \
560 __put_user((id), &ent[nr]._id); \
561 __put_user((val), &ent[nr]._val); \
533 } while (0) 562 } while (0)
534 563
535 csp -= 2 * sizeof(unsigned long); 564 csp -= 2 * sizeof(unsigned long);
536 NEW_AUX_ENT(0, AT_NULL, 0); 565 NEW_AUX_ENT(0, AT_NULL, 0);
537 if (k_platform) { 566 if (k_platform) {
538 csp -= 2 * sizeof(unsigned long); 567 csp -= 2 * sizeof(unsigned long);
539 NEW_AUX_ENT(0, AT_PLATFORM, (elf_addr_t)(unsigned long) u_platform); 568 NEW_AUX_ENT(0, AT_PLATFORM,
569 (elf_addr_t) (unsigned long) u_platform);
540 } 570 }
541 571
542 csp -= DLINFO_ITEMS * 2 * sizeof(unsigned long); 572 csp -= DLINFO_ITEMS * 2 * sizeof(unsigned long);
543 NEW_AUX_ENT( 0, AT_HWCAP, hwcap); 573 NEW_AUX_ENT( 0, AT_HWCAP, hwcap);
544 NEW_AUX_ENT( 1, AT_PAGESZ, PAGE_SIZE); 574 NEW_AUX_ENT( 1, AT_PAGESZ, PAGE_SIZE);
545 NEW_AUX_ENT( 2, AT_CLKTCK, CLOCKS_PER_SEC); 575 NEW_AUX_ENT( 2, AT_CLKTCK, CLOCKS_PER_SEC);
546 NEW_AUX_ENT( 3, AT_PHDR, exec_params->ph_addr); 576 NEW_AUX_ENT( 3, AT_PHDR, exec_params->ph_addr);
547 NEW_AUX_ENT( 4, AT_PHENT, sizeof(struct elf_phdr)); 577 NEW_AUX_ENT( 4, AT_PHENT, sizeof(struct elf_phdr));
548 NEW_AUX_ENT( 5, AT_PHNUM, exec_params->hdr.e_phnum); 578 NEW_AUX_ENT( 5, AT_PHNUM, exec_params->hdr.e_phnum);
549 NEW_AUX_ENT( 6, AT_BASE, interp_params->elfhdr_addr); 579 NEW_AUX_ENT( 6, AT_BASE, interp_params->elfhdr_addr);
550 NEW_AUX_ENT( 7, AT_FLAGS, 0); 580 NEW_AUX_ENT( 7, AT_FLAGS, 0);
551 NEW_AUX_ENT( 8, AT_ENTRY, exec_params->entry_addr); 581 NEW_AUX_ENT( 8, AT_ENTRY, exec_params->entry_addr);
552 NEW_AUX_ENT( 9, AT_UID, (elf_addr_t) current->uid); 582 NEW_AUX_ENT( 9, AT_UID, (elf_addr_t) current->uid);
553 NEW_AUX_ENT(10, AT_EUID, (elf_addr_t) current->euid); 583 NEW_AUX_ENT(10, AT_EUID, (elf_addr_t) current->euid);
554 NEW_AUX_ENT(11, AT_GID, (elf_addr_t) current->gid); 584 NEW_AUX_ENT(11, AT_GID, (elf_addr_t) current->gid);
555 NEW_AUX_ENT(12, AT_EGID, (elf_addr_t) current->egid); 585 NEW_AUX_ENT(12, AT_EGID, (elf_addr_t) current->egid);
556 586
557#ifdef ARCH_DLINFO 587#ifdef ARCH_DLINFO
558 /* ARCH_DLINFO must come last so platform specific code can enforce 588 /* ARCH_DLINFO must come last so platform specific code can enforce
@@ -578,7 +608,8 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
578#ifdef CONFIG_MMU 608#ifdef CONFIG_MMU
579 current->mm->arg_start = bprm->p; 609 current->mm->arg_start = bprm->p;
580#else 610#else
581 current->mm->arg_start = current->mm->start_stack - (MAX_ARG_PAGES * PAGE_SIZE - bprm->p); 611 current->mm->arg_start = current->mm->start_stack -
612 (MAX_ARG_PAGES * PAGE_SIZE - bprm->p);
582#endif 613#endif
583 614
584 p = (char __user *) current->mm->arg_start; 615 p = (char __user *) current->mm->arg_start;
@@ -606,7 +637,7 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
606 637
607 mm->start_stack = (unsigned long) sp; 638 mm->start_stack = (unsigned long) sp;
608 return 0; 639 return 0;
609} /* end create_elf_fdpic_tables() */ 640}
610 641
611/*****************************************************************************/ 642/*****************************************************************************/
612/* 643/*
@@ -614,7 +645,8 @@ static int create_elf_fdpic_tables(struct linux_binprm *bprm,
614 * the stack 645 * the stack
615 */ 646 */
616#ifndef CONFIG_MMU 647#ifndef CONFIG_MMU
617static int elf_fdpic_transfer_args_to_stack(struct linux_binprm *bprm, unsigned long *_sp) 648static int elf_fdpic_transfer_args_to_stack(struct linux_binprm *bprm,
649 unsigned long *_sp)
618{ 650{
619 unsigned long index, stop, sp; 651 unsigned long index, stop, sp;
620 char *src; 652 char *src;
@@ -635,9 +667,9 @@ static int elf_fdpic_transfer_args_to_stack(struct linux_binprm *bprm, unsigned
635 667
636 *_sp = (*_sp - (MAX_ARG_PAGES * PAGE_SIZE - bprm->p)) & ~15; 668 *_sp = (*_sp - (MAX_ARG_PAGES * PAGE_SIZE - bprm->p)) & ~15;
637 669
638 out: 670out:
639 return ret; 671 return ret;
640} /* end elf_fdpic_transfer_args_to_stack() */ 672}
641#endif 673#endif
642 674
643/*****************************************************************************/ 675/*****************************************************************************/
@@ -712,17 +744,18 @@ static int elf_fdpic_map_file(struct elf_fdpic_params *params,
712 seg = loadmap->segs; 744 seg = loadmap->segs;
713 for (loop = loadmap->nsegs; loop > 0; loop--, seg++) { 745 for (loop = loadmap->nsegs; loop > 0; loop--, seg++) {
714 if (params->hdr.e_entry >= seg->p_vaddr && 746 if (params->hdr.e_entry >= seg->p_vaddr &&
715 params->hdr.e_entry < seg->p_vaddr + seg->p_memsz 747 params->hdr.e_entry < seg->p_vaddr + seg->p_memsz) {
716 ) {
717 params->entry_addr = 748 params->entry_addr =
718 (params->hdr.e_entry - seg->p_vaddr) + seg->addr; 749 (params->hdr.e_entry - seg->p_vaddr) +
750 seg->addr;
719 break; 751 break;
720 } 752 }
721 } 753 }
722 } 754 }
723 755
724 /* determine where the program header table has wound up if mapped */ 756 /* determine where the program header table has wound up if mapped */
725 stop = params->hdr.e_phoff + params->hdr.e_phnum * sizeof (struct elf_phdr); 757 stop = params->hdr.e_phoff;
758 stop += params->hdr.e_phnum * sizeof (struct elf_phdr);
726 phdr = params->phdrs; 759 phdr = params->phdrs;
727 760
728 for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) { 761 for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) {
@@ -736,9 +769,11 @@ static int elf_fdpic_map_file(struct elf_fdpic_params *params,
736 seg = loadmap->segs; 769 seg = loadmap->segs;
737 for (loop = loadmap->nsegs; loop > 0; loop--, seg++) { 770 for (loop = loadmap->nsegs; loop > 0; loop--, seg++) {
738 if (phdr->p_vaddr >= seg->p_vaddr && 771 if (phdr->p_vaddr >= seg->p_vaddr &&
739 phdr->p_vaddr + phdr->p_filesz <= seg->p_vaddr + seg->p_memsz 772 phdr->p_vaddr + phdr->p_filesz <=
740 ) { 773 seg->p_vaddr + seg->p_memsz) {
741 params->ph_addr = (phdr->p_vaddr - seg->p_vaddr) + seg->addr + 774 params->ph_addr =
775 (phdr->p_vaddr - seg->p_vaddr) +
776 seg->addr +
742 params->hdr.e_phoff - phdr->p_offset; 777 params->hdr.e_phoff - phdr->p_offset;
743 break; 778 break;
744 } 779 }
@@ -755,18 +790,22 @@ static int elf_fdpic_map_file(struct elf_fdpic_params *params,
755 seg = loadmap->segs; 790 seg = loadmap->segs;
756 for (loop = loadmap->nsegs; loop > 0; loop--, seg++) { 791 for (loop = loadmap->nsegs; loop > 0; loop--, seg++) {
757 if (phdr->p_vaddr >= seg->p_vaddr && 792 if (phdr->p_vaddr >= seg->p_vaddr &&
758 phdr->p_vaddr + phdr->p_memsz <= seg->p_vaddr + seg->p_memsz 793 phdr->p_vaddr + phdr->p_memsz <=
759 ) { 794 seg->p_vaddr + seg->p_memsz) {
760 params->dynamic_addr = (phdr->p_vaddr - seg->p_vaddr) + seg->addr; 795 params->dynamic_addr =
761 796 (phdr->p_vaddr - seg->p_vaddr) +
762 /* check the dynamic section contains at least one item, and that 797 seg->addr;
763 * the last item is a NULL entry */ 798
799 /* check the dynamic section contains at least
800 * one item, and that the last item is a NULL
801 * entry */
764 if (phdr->p_memsz == 0 || 802 if (phdr->p_memsz == 0 ||
765 phdr->p_memsz % sizeof(Elf32_Dyn) != 0) 803 phdr->p_memsz % sizeof(Elf32_Dyn) != 0)
766 goto dynamic_error; 804 goto dynamic_error;
767 805
768 tmp = phdr->p_memsz / sizeof(Elf32_Dyn); 806 tmp = phdr->p_memsz / sizeof(Elf32_Dyn);
769 if (((Elf32_Dyn *) params->dynamic_addr)[tmp - 1].d_tag != 0) 807 if (((Elf32_Dyn *)
808 params->dynamic_addr)[tmp - 1].d_tag != 0)
770 goto dynamic_error; 809 goto dynamic_error;
771 break; 810 break;
772 } 811 }
@@ -775,8 +814,8 @@ static int elf_fdpic_map_file(struct elf_fdpic_params *params,
775 } 814 }
776 815
777 /* now elide adjacent segments in the load map on MMU linux 816 /* now elide adjacent segments in the load map on MMU linux
778 * - on uClinux the holes between may actually be filled with system stuff or stuff from 817 * - on uClinux the holes between may actually be filled with system
779 * other processes 818 * stuff or stuff from other processes
780 */ 819 */
781#ifdef CONFIG_MMU 820#ifdef CONFIG_MMU
782 nloads = loadmap->nsegs; 821 nloads = loadmap->nsegs;
@@ -787,7 +826,9 @@ static int elf_fdpic_map_file(struct elf_fdpic_params *params,
787 if (seg->p_vaddr - mseg->p_vaddr == seg->addr - mseg->addr) { 826 if (seg->p_vaddr - mseg->p_vaddr == seg->addr - mseg->addr) {
788 load_addr = PAGE_ALIGN(mseg->addr + mseg->p_memsz); 827 load_addr = PAGE_ALIGN(mseg->addr + mseg->p_memsz);
789 if (load_addr == (seg->addr & PAGE_MASK)) { 828 if (load_addr == (seg->addr & PAGE_MASK)) {
790 mseg->p_memsz += load_addr - (mseg->addr + mseg->p_memsz); 829 mseg->p_memsz +=
830 load_addr -
831 (mseg->addr + mseg->p_memsz);
791 mseg->p_memsz += seg->addr & ~PAGE_MASK; 832 mseg->p_memsz += seg->addr & ~PAGE_MASK;
792 mseg->p_memsz += seg->p_memsz; 833 mseg->p_memsz += seg->p_memsz;
793 loadmap->nsegs--; 834 loadmap->nsegs--;
@@ -815,20 +856,21 @@ static int elf_fdpic_map_file(struct elf_fdpic_params *params,
815 856
816 return 0; 857 return 0;
817 858
818 dynamic_error: 859dynamic_error:
819 printk("ELF FDPIC %s with invalid DYNAMIC section (inode=%lu)\n", 860 printk("ELF FDPIC %s with invalid DYNAMIC section (inode=%lu)\n",
820 what, file->f_dentry->d_inode->i_ino); 861 what, file->f_dentry->d_inode->i_ino);
821 return -ELIBBAD; 862 return -ELIBBAD;
822} /* end elf_fdpic_map_file() */ 863}
823 864
824/*****************************************************************************/ 865/*****************************************************************************/
825/* 866/*
826 * map a file with constant displacement under uClinux 867 * map a file with constant displacement under uClinux
827 */ 868 */
828#ifndef CONFIG_MMU 869#ifndef CONFIG_MMU
829static int elf_fdpic_map_file_constdisp_on_uclinux(struct elf_fdpic_params *params, 870static int elf_fdpic_map_file_constdisp_on_uclinux(
830 struct file *file, 871 struct elf_fdpic_params *params,
831 struct mm_struct *mm) 872 struct file *file,
873 struct mm_struct *mm)
832{ 874{
833 struct elf32_fdpic_loadseg *seg; 875 struct elf32_fdpic_loadseg *seg;
834 struct elf32_phdr *phdr; 876 struct elf32_phdr *phdr;
@@ -839,7 +881,8 @@ static int elf_fdpic_map_file_constdisp_on_uclinux(struct elf_fdpic_params *para
839 load_addr = params->load_addr; 881 load_addr = params->load_addr;
840 seg = params->loadmap->segs; 882 seg = params->loadmap->segs;
841 883
842 /* determine the bounds of the contiguous overall allocation we must make */ 884 /* determine the bounds of the contiguous overall allocation we must
885 * make */
843 phdr = params->phdrs; 886 phdr = params->phdrs;
844 for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) { 887 for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) {
845 if (params->phdrs[loop].p_type != PT_LOAD) 888 if (params->phdrs[loop].p_type != PT_LOAD)
@@ -860,7 +903,7 @@ static int elf_fdpic_map_file_constdisp_on_uclinux(struct elf_fdpic_params *para
860 maddr = do_mmap(NULL, load_addr, top - base, 903 maddr = do_mmap(NULL, load_addr, top - base,
861 PROT_READ | PROT_WRITE | PROT_EXEC, mflags, 0); 904 PROT_READ | PROT_WRITE | PROT_EXEC, mflags, 0);
862 up_write(&mm->mmap_sem); 905 up_write(&mm->mmap_sem);
863 if (IS_ERR((void *) maddr)) 906 if (IS_ERR_VALUE(maddr))
864 return (int) maddr; 907 return (int) maddr;
865 908
866 if (load_addr != 0) 909 if (load_addr != 0)
@@ -878,7 +921,8 @@ static int elf_fdpic_map_file_constdisp_on_uclinux(struct elf_fdpic_params *para
878 seg->p_vaddr = phdr->p_vaddr; 921 seg->p_vaddr = phdr->p_vaddr;
879 seg->p_memsz = phdr->p_memsz; 922 seg->p_memsz = phdr->p_memsz;
880 923
881 ret = file->f_op->read(file, (void *) seg->addr, phdr->p_filesz, &fpos); 924 ret = file->f_op->read(file, (void *) seg->addr,
925 phdr->p_filesz, &fpos);
882 if (ret < 0) 926 if (ret < 0)
883 return ret; 927 return ret;
884 928
@@ -895,8 +939,7 @@ static int elf_fdpic_map_file_constdisp_on_uclinux(struct elf_fdpic_params *para
895 if (phdr->p_flags & PF_X) { 939 if (phdr->p_flags & PF_X) {
896 mm->start_code = seg->addr; 940 mm->start_code = seg->addr;
897 mm->end_code = seg->addr + phdr->p_memsz; 941 mm->end_code = seg->addr + phdr->p_memsz;
898 } 942 } else if (!mm->start_data) {
899 else if (!mm->start_data) {
900 mm->start_data = seg->addr; 943 mm->start_data = seg->addr;
901#ifndef CONFIG_MMU 944#ifndef CONFIG_MMU
902 mm->end_data = seg->addr + phdr->p_memsz; 945 mm->end_data = seg->addr + phdr->p_memsz;
@@ -913,7 +956,7 @@ static int elf_fdpic_map_file_constdisp_on_uclinux(struct elf_fdpic_params *para
913 } 956 }
914 957
915 return 0; 958 return 0;
916} /* end elf_fdpic_map_file_constdisp_on_uclinux() */ 959}
917#endif 960#endif
918 961
919/*****************************************************************************/ 962/*****************************************************************************/
@@ -974,14 +1017,14 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
974 1017
975 case ELF_FDPIC_FLAG_CONSTDISP: 1018 case ELF_FDPIC_FLAG_CONSTDISP:
976 /* constant displacement 1019 /* constant displacement
977 * - can be mapped anywhere, but must be mapped as a unit 1020 * - can be mapped anywhere, but must be mapped as a
1021 * unit
978 */ 1022 */
979 if (!dvset) { 1023 if (!dvset) {
980 maddr = load_addr; 1024 maddr = load_addr;
981 delta_vaddr = phdr->p_vaddr; 1025 delta_vaddr = phdr->p_vaddr;
982 dvset = 1; 1026 dvset = 1;
983 } 1027 } else {
984 else {
985 maddr = load_addr + phdr->p_vaddr - delta_vaddr; 1028 maddr = load_addr + phdr->p_vaddr - delta_vaddr;
986 flags |= MAP_FIXED; 1029 flags |= MAP_FIXED;
987 } 1030 }
@@ -1005,13 +1048,14 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
1005 up_write(&mm->mmap_sem); 1048 up_write(&mm->mmap_sem);
1006 1049
1007 kdebug("mmap[%d] <file> sz=%lx pr=%x fl=%x of=%lx --> %08lx", 1050 kdebug("mmap[%d] <file> sz=%lx pr=%x fl=%x of=%lx --> %08lx",
1008 loop, phdr->p_memsz + disp, prot, flags, phdr->p_offset - disp, 1051 loop, phdr->p_memsz + disp, prot, flags,
1009 maddr); 1052 phdr->p_offset - disp, maddr);
1010 1053
1011 if (IS_ERR((void *) maddr)) 1054 if (IS_ERR_VALUE(maddr))
1012 return (int) maddr; 1055 return (int) maddr;
1013 1056
1014 if ((params->flags & ELF_FDPIC_FLAG_ARRANGEMENT) == ELF_FDPIC_FLAG_CONTIGUOUS) 1057 if ((params->flags & ELF_FDPIC_FLAG_ARRANGEMENT) ==
1058 ELF_FDPIC_FLAG_CONTIGUOUS)
1015 load_addr += PAGE_ALIGN(phdr->p_memsz + disp); 1059 load_addr += PAGE_ALIGN(phdr->p_memsz + disp);
1016 1060
1017 seg->addr = maddr + disp; 1061 seg->addr = maddr + disp;
@@ -1022,7 +1066,8 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
1022 if (phdr->p_offset == 0) 1066 if (phdr->p_offset == 0)
1023 params->elfhdr_addr = seg->addr; 1067 params->elfhdr_addr = seg->addr;
1024 1068
1025 /* clear the bit between beginning of mapping and beginning of PT_LOAD */ 1069 /* clear the bit between beginning of mapping and beginning of
1070 * PT_LOAD */
1026 if (prot & PROT_WRITE && disp > 0) { 1071 if (prot & PROT_WRITE && disp > 0) {
1027 kdebug("clear[%d] ad=%lx sz=%lx", loop, maddr, disp); 1072 kdebug("clear[%d] ad=%lx sz=%lx", loop, maddr, disp);
1028 clear_user((void __user *) maddr, disp); 1073 clear_user((void __user *) maddr, disp);
@@ -1038,19 +1083,20 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
1038 excess1 = PAGE_SIZE - ((maddr + phdr->p_filesz) & ~PAGE_MASK); 1083 excess1 = PAGE_SIZE - ((maddr + phdr->p_filesz) & ~PAGE_MASK);
1039 1084
1040#ifdef CONFIG_MMU 1085#ifdef CONFIG_MMU
1041
1042 if (excess > excess1) { 1086 if (excess > excess1) {
1043 unsigned long xaddr = maddr + phdr->p_filesz + excess1; 1087 unsigned long xaddr = maddr + phdr->p_filesz + excess1;
1044 unsigned long xmaddr; 1088 unsigned long xmaddr;
1045 1089
1046 flags |= MAP_FIXED | MAP_ANONYMOUS; 1090 flags |= MAP_FIXED | MAP_ANONYMOUS;
1047 down_write(&mm->mmap_sem); 1091 down_write(&mm->mmap_sem);
1048 xmaddr = do_mmap(NULL, xaddr, excess - excess1, prot, flags, 0); 1092 xmaddr = do_mmap(NULL, xaddr, excess - excess1,
1093 prot, flags, 0);
1049 up_write(&mm->mmap_sem); 1094 up_write(&mm->mmap_sem);
1050 1095
1051 kdebug("mmap[%d] <anon>" 1096 kdebug("mmap[%d] <anon>"
1052 " ad=%lx sz=%lx pr=%x fl=%x of=0 --> %08lx", 1097 " ad=%lx sz=%lx pr=%x fl=%x of=0 --> %08lx",
1053 loop, xaddr, excess - excess1, prot, flags, xmaddr); 1098 loop, xaddr, excess - excess1, prot, flags,
1099 xmaddr);
1054 1100
1055 if (xmaddr != xaddr) 1101 if (xmaddr != xaddr)
1056 return -ENOMEM; 1102 return -ENOMEM;
@@ -1059,7 +1105,8 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
1059 if (prot & PROT_WRITE && excess1 > 0) { 1105 if (prot & PROT_WRITE && excess1 > 0) {
1060 kdebug("clear[%d] ad=%lx sz=%lx", 1106 kdebug("clear[%d] ad=%lx sz=%lx",
1061 loop, maddr + phdr->p_filesz, excess1); 1107 loop, maddr + phdr->p_filesz, excess1);
1062 clear_user((void __user *) maddr + phdr->p_filesz, excess1); 1108 clear_user((void __user *) maddr + phdr->p_filesz,
1109 excess1);
1063 } 1110 }
1064 1111
1065#else 1112#else
@@ -1074,8 +1121,7 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
1074 if (phdr->p_flags & PF_X) { 1121 if (phdr->p_flags & PF_X) {
1075 mm->start_code = maddr; 1122 mm->start_code = maddr;
1076 mm->end_code = maddr + phdr->p_memsz; 1123 mm->end_code = maddr + phdr->p_memsz;
1077 } 1124 } else if (!mm->start_data) {
1078 else if (!mm->start_data) {
1079 mm->start_data = maddr; 1125 mm->start_data = maddr;
1080 mm->end_data = maddr + phdr->p_memsz; 1126 mm->end_data = maddr + phdr->p_memsz;
1081 } 1127 }
@@ -1085,4 +1131,662 @@ static int elf_fdpic_map_file_by_direct_mmap(struct elf_fdpic_params *params,
1085 } 1131 }
1086 1132
1087 return 0; 1133 return 0;
1088} /* end elf_fdpic_map_file_by_direct_mmap() */ 1134}
1135
1136/*****************************************************************************/
1137/*
1138 * ELF-FDPIC core dumper
1139 *
1140 * Modelled on fs/exec.c:aout_core_dump()
1141 * Jeremy Fitzhardinge <jeremy@sw.oz.au>
1142 *
1143 * Modelled on fs/binfmt_elf.c core dumper
1144 */
1145#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE)
1146
1147/*
1148 * These are the only things you should do on a core-file: use only these
1149 * functions to write out all the necessary info.
1150 */
1151static int dump_write(struct file *file, const void *addr, int nr)
1152{
1153 return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
1154}
1155
1156static int dump_seek(struct file *file, loff_t off)
1157{
1158 if (file->f_op->llseek) {
1159 if (file->f_op->llseek(file, off, SEEK_SET) != off)
1160 return 0;
1161 } else {
1162 file->f_pos = off;
1163 }
1164 return 1;
1165}
1166
1167/*
1168 * Decide whether a segment is worth dumping; default is yes to be
1169 * sure (missing info is worse than too much; etc).
1170 * Personally I'd include everything, and use the coredump limit...
1171 *
1172 * I think we should skip something. But I am not sure how. H.J.
1173 */
1174static int maydump(struct vm_area_struct *vma)
1175{
1176 /* Do not dump I/O mapped devices or special mappings */
1177 if (vma->vm_flags & (VM_IO | VM_RESERVED)) {
1178 kdcore("%08lx: %08lx: no (IO)", vma->vm_start, vma->vm_flags);
1179 return 0;
1180 }
1181
1182 /* If we may not read the contents, don't allow us to dump
1183 * them either. "dump_write()" can't handle it anyway.
1184 */
1185 if (!(vma->vm_flags & VM_READ)) {
1186 kdcore("%08lx: %08lx: no (!read)", vma->vm_start, vma->vm_flags);
1187 return 0;
1188 }
1189
1190 /* Dump shared memory only if mapped from an anonymous file. */
1191 if (vma->vm_flags & VM_SHARED) {
1192 if (vma->vm_file->f_dentry->d_inode->i_nlink == 0) {
1193 kdcore("%08lx: %08lx: no (share)", vma->vm_start, vma->vm_flags);
1194 return 1;
1195 }
1196
1197 kdcore("%08lx: %08lx: no (share)", vma->vm_start, vma->vm_flags);
1198 return 0;
1199 }
1200
1201#ifdef CONFIG_MMU
1202 /* If it hasn't been written to, don't write it out */
1203 if (!vma->anon_vma) {
1204 kdcore("%08lx: %08lx: no (!anon)", vma->vm_start, vma->vm_flags);
1205 return 0;
1206 }
1207#endif
1208
1209 kdcore("%08lx: %08lx: yes", vma->vm_start, vma->vm_flags);
1210 return 1;
1211}
1212
1213/* An ELF note in memory */
1214struct memelfnote
1215{
1216 const char *name;
1217 int type;
1218 unsigned int datasz;
1219 void *data;
1220};
1221
1222static int notesize(struct memelfnote *en)
1223{
1224 int sz;
1225
1226 sz = sizeof(struct elf_note);
1227 sz += roundup(strlen(en->name) + 1, 4);
1228 sz += roundup(en->datasz, 4);
1229
1230 return sz;
1231}
1232
1233/* #define DEBUG */
1234
1235#define DUMP_WRITE(addr, nr) \
1236 do { if (!dump_write(file, (addr), (nr))) return 0; } while(0)
1237#define DUMP_SEEK(off) \
1238 do { if (!dump_seek(file, (off))) return 0; } while(0)
1239
1240static int writenote(struct memelfnote *men, struct file *file)
1241{
1242 struct elf_note en;
1243
1244 en.n_namesz = strlen(men->name) + 1;
1245 en.n_descsz = men->datasz;
1246 en.n_type = men->type;
1247
1248 DUMP_WRITE(&en, sizeof(en));
1249 DUMP_WRITE(men->name, en.n_namesz);
1250 /* XXX - cast from long long to long to avoid need for libgcc.a */
1251 DUMP_SEEK(roundup((unsigned long)file->f_pos, 4)); /* XXX */
1252 DUMP_WRITE(men->data, men->datasz);
1253 DUMP_SEEK(roundup((unsigned long)file->f_pos, 4)); /* XXX */
1254
1255 return 1;
1256}
1257#undef DUMP_WRITE
1258#undef DUMP_SEEK
1259
1260#define DUMP_WRITE(addr, nr) \
1261 if ((size += (nr)) > limit || !dump_write(file, (addr), (nr))) \
1262 goto end_coredump;
1263#define DUMP_SEEK(off) \
1264 if (!dump_seek(file, (off))) \
1265 goto end_coredump;
1266
1267static inline void fill_elf_fdpic_header(struct elfhdr *elf, int segs)
1268{
1269 memcpy(elf->e_ident, ELFMAG, SELFMAG);
1270 elf->e_ident[EI_CLASS] = ELF_CLASS;
1271 elf->e_ident[EI_DATA] = ELF_DATA;
1272 elf->e_ident[EI_VERSION] = EV_CURRENT;
1273 elf->e_ident[EI_OSABI] = ELF_OSABI;
1274 memset(elf->e_ident+EI_PAD, 0, EI_NIDENT-EI_PAD);
1275
1276 elf->e_type = ET_CORE;
1277 elf->e_machine = ELF_ARCH;
1278 elf->e_version = EV_CURRENT;
1279 elf->e_entry = 0;
1280 elf->e_phoff = sizeof(struct elfhdr);
1281 elf->e_shoff = 0;
1282 elf->e_flags = ELF_FDPIC_CORE_EFLAGS;
1283 elf->e_ehsize = sizeof(struct elfhdr);
1284 elf->e_phentsize = sizeof(struct elf_phdr);
1285 elf->e_phnum = segs;
1286 elf->e_shentsize = 0;
1287 elf->e_shnum = 0;
1288 elf->e_shstrndx = 0;
1289 return;
1290}
1291
1292static inline void fill_elf_note_phdr(struct elf_phdr *phdr, int sz, loff_t offset)
1293{
1294 phdr->p_type = PT_NOTE;
1295 phdr->p_offset = offset;
1296 phdr->p_vaddr = 0;
1297 phdr->p_paddr = 0;
1298 phdr->p_filesz = sz;
1299 phdr->p_memsz = 0;
1300 phdr->p_flags = 0;
1301 phdr->p_align = 0;
1302 return;
1303}
1304
1305static inline void fill_note(struct memelfnote *note, const char *name, int type,
1306 unsigned int sz, void *data)
1307{
1308 note->name = name;
1309 note->type = type;
1310 note->datasz = sz;
1311 note->data = data;
1312 return;
1313}
1314
1315/*
1316 * fill up all the fields in prstatus from the given task struct, except
1317 * registers which need to be filled up seperately.
1318 */
1319static void fill_prstatus(struct elf_prstatus *prstatus,
1320 struct task_struct *p, long signr)
1321{
1322 prstatus->pr_info.si_signo = prstatus->pr_cursig = signr;
1323 prstatus->pr_sigpend = p->pending.signal.sig[0];
1324 prstatus->pr_sighold = p->blocked.sig[0];
1325 prstatus->pr_pid = p->pid;
1326 prstatus->pr_ppid = p->parent->pid;
1327 prstatus->pr_pgrp = process_group(p);
1328 prstatus->pr_sid = p->signal->session;
1329 if (thread_group_leader(p)) {
1330 /*
1331 * This is the record for the group leader. Add in the
1332 * cumulative times of previous dead threads. This total
1333 * won't include the time of each live thread whose state
1334 * is included in the core dump. The final total reported
1335 * to our parent process when it calls wait4 will include
1336 * those sums as well as the little bit more time it takes
1337 * this and each other thread to finish dying after the
1338 * core dump synchronization phase.
1339 */
1340 cputime_to_timeval(cputime_add(p->utime, p->signal->utime),
1341 &prstatus->pr_utime);
1342 cputime_to_timeval(cputime_add(p->stime, p->signal->stime),
1343 &prstatus->pr_stime);
1344 } else {
1345 cputime_to_timeval(p->utime, &prstatus->pr_utime);
1346 cputime_to_timeval(p->stime, &prstatus->pr_stime);
1347 }
1348 cputime_to_timeval(p->signal->cutime, &prstatus->pr_cutime);
1349 cputime_to_timeval(p->signal->cstime, &prstatus->pr_cstime);
1350
1351 prstatus->pr_exec_fdpic_loadmap = p->mm->context.exec_fdpic_loadmap;
1352 prstatus->pr_interp_fdpic_loadmap = p->mm->context.interp_fdpic_loadmap;
1353}
1354
1355static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
1356 struct mm_struct *mm)
1357{
1358 unsigned int i, len;
1359
1360 /* first copy the parameters from user space */
1361 memset(psinfo, 0, sizeof(struct elf_prpsinfo));
1362
1363 len = mm->arg_end - mm->arg_start;
1364 if (len >= ELF_PRARGSZ)
1365 len = ELF_PRARGSZ - 1;
1366 if (copy_from_user(&psinfo->pr_psargs,
1367 (const char __user *) mm->arg_start, len))
1368 return -EFAULT;
1369 for (i = 0; i < len; i++)
1370 if (psinfo->pr_psargs[i] == 0)
1371 psinfo->pr_psargs[i] = ' ';
1372 psinfo->pr_psargs[len] = 0;
1373
1374 psinfo->pr_pid = p->pid;
1375 psinfo->pr_ppid = p->parent->pid;
1376 psinfo->pr_pgrp = process_group(p);
1377 psinfo->pr_sid = p->signal->session;
1378
1379 i = p->state ? ffz(~p->state) + 1 : 0;
1380 psinfo->pr_state = i;
1381 psinfo->pr_sname = (i > 5) ? '.' : "RSDTZW"[i];
1382 psinfo->pr_zomb = psinfo->pr_sname == 'Z';
1383 psinfo->pr_nice = task_nice(p);
1384 psinfo->pr_flag = p->flags;
1385 SET_UID(psinfo->pr_uid, p->uid);
1386 SET_GID(psinfo->pr_gid, p->gid);
1387 strncpy(psinfo->pr_fname, p->comm, sizeof(psinfo->pr_fname));
1388
1389 return 0;
1390}
1391
1392/* Here is the structure in which status of each thread is captured. */
1393struct elf_thread_status
1394{
1395 struct list_head list;
1396 struct elf_prstatus prstatus; /* NT_PRSTATUS */
1397 elf_fpregset_t fpu; /* NT_PRFPREG */
1398 struct task_struct *thread;
1399#ifdef ELF_CORE_COPY_XFPREGS
1400 elf_fpxregset_t xfpu; /* NT_PRXFPREG */
1401#endif
1402 struct memelfnote notes[3];
1403 int num_notes;
1404};
1405
1406/*
1407 * In order to add the specific thread information for the elf file format,
1408 * we need to keep a linked list of every thread's pr_status and then create
1409 * a single section for them in the final core file.
1410 */
1411static int elf_dump_thread_status(long signr, struct elf_thread_status *t)
1412{
1413 struct task_struct *p = t->thread;
1414 int sz = 0;
1415
1416 t->num_notes = 0;
1417
1418 fill_prstatus(&t->prstatus, p, signr);
1419 elf_core_copy_task_regs(p, &t->prstatus.pr_reg);
1420
1421 fill_note(&t->notes[0], "CORE", NT_PRSTATUS, sizeof(t->prstatus),
1422 &t->prstatus);
1423 t->num_notes++;
1424 sz += notesize(&t->notes[0]);
1425
1426 t->prstatus.pr_fpvalid = elf_core_copy_task_fpregs(p, NULL, &t->fpu);
1427 if (t->prstatus.pr_fpvalid) {
1428 fill_note(&t->notes[1], "CORE", NT_PRFPREG, sizeof(t->fpu),
1429 &t->fpu);
1430 t->num_notes++;
1431 sz += notesize(&t->notes[1]);
1432 }
1433
1434#ifdef ELF_CORE_COPY_XFPREGS
1435 if (elf_core_copy_task_xfpregs(p, &t->xfpu)) {
1436 fill_note(&t->notes[2], "LINUX", NT_PRXFPREG, sizeof(t->xfpu),
1437 &t->xfpu);
1438 t->num_notes++;
1439 sz += notesize(&t->notes[2]);
1440 }
1441#endif
1442 return sz;
1443}
1444
1445/*
1446 * dump the segments for an MMU process
1447 */
1448#ifdef CONFIG_MMU
1449static int elf_fdpic_dump_segments(struct file *file, struct mm_struct *mm,
1450 size_t *size, unsigned long *limit)
1451{
1452 struct vm_area_struct *vma;
1453
1454 for (vma = current->mm->mmap; vma; vma = vma->vm_next) {
1455 unsigned long addr;
1456
1457 if (!maydump(vma))
1458 continue;
1459
1460 for (addr = vma->vm_start;
1461 addr < vma->vm_end;
1462 addr += PAGE_SIZE
1463 ) {
1464 struct vm_area_struct *vma;
1465 struct page *page;
1466
1467 if (get_user_pages(current, current->mm, addr, 1, 0, 1,
1468 &page, &vma) <= 0) {
1469 DUMP_SEEK(file->f_pos + PAGE_SIZE);
1470 }
1471 else if (page == ZERO_PAGE(addr)) {
1472 DUMP_SEEK(file->f_pos + PAGE_SIZE);
1473 page_cache_release(page);
1474 }
1475 else {
1476 void *kaddr;
1477
1478 flush_cache_page(vma, addr, page_to_pfn(page));
1479 kaddr = kmap(page);
1480 if ((*size += PAGE_SIZE) > *limit ||
1481 !dump_write(file, kaddr, PAGE_SIZE)
1482 ) {
1483 kunmap(page);
1484 page_cache_release(page);
1485 return -EIO;
1486 }
1487 kunmap(page);
1488 page_cache_release(page);
1489 }
1490 }
1491 }
1492
1493 return 0;
1494
1495end_coredump:
1496 return -EFBIG;
1497}
1498#endif
1499
1500/*
1501 * dump the segments for a NOMMU process
1502 */
1503#ifndef CONFIG_MMU
1504static int elf_fdpic_dump_segments(struct file *file, struct mm_struct *mm,
1505 size_t *size, unsigned long *limit)
1506{
1507 struct vm_list_struct *vml;
1508
1509 for (vml = current->mm->context.vmlist; vml; vml = vml->next) {
1510 struct vm_area_struct *vma = vml->vma;
1511
1512 if (!maydump(vma))
1513 continue;
1514
1515 if ((*size += PAGE_SIZE) > *limit)
1516 return -EFBIG;
1517
1518 if (!dump_write(file, (void *) vma->vm_start,
1519 vma->vm_end - vma->vm_start))
1520 return -EIO;
1521 }
1522
1523 return 0;
1524}
1525#endif
1526
1527/*
1528 * Actual dumper
1529 *
1530 * This is a two-pass process; first we find the offsets of the bits,
1531 * and then they are actually written out. If we run out of core limit
1532 * we just truncate.
1533 */
1534static int elf_fdpic_core_dump(long signr, struct pt_regs *regs,
1535 struct file *file)
1536{
1537#define NUM_NOTES 6
1538 int has_dumped = 0;
1539 mm_segment_t fs;
1540 int segs;
1541 size_t size = 0;
1542 int i;
1543 struct vm_area_struct *vma;
1544 struct elfhdr *elf = NULL;
1545 loff_t offset = 0, dataoff;
1546 unsigned long limit = current->signal->rlim[RLIMIT_CORE].rlim_cur;
1547 int numnote;
1548 struct memelfnote *notes = NULL;
1549 struct elf_prstatus *prstatus = NULL; /* NT_PRSTATUS */
1550 struct elf_prpsinfo *psinfo = NULL; /* NT_PRPSINFO */
1551 struct task_struct *g, *p;
1552 LIST_HEAD(thread_list);
1553 struct list_head *t;
1554 elf_fpregset_t *fpu = NULL;
1555#ifdef ELF_CORE_COPY_XFPREGS
1556 elf_fpxregset_t *xfpu = NULL;
1557#endif
1558 int thread_status_size = 0;
1559#ifndef CONFIG_MMU
1560 struct vm_list_struct *vml;
1561#endif
1562 elf_addr_t *auxv;
1563
1564 /*
1565 * We no longer stop all VM operations.
1566 *
1567 * This is because those proceses that could possibly change map_count
1568 * or the mmap / vma pages are now blocked in do_exit on current
1569 * finishing this core dump.
1570 *
1571 * Only ptrace can touch these memory addresses, but it doesn't change
1572 * the map_count or the pages allocated. So no possibility of crashing
1573 * exists while dumping the mm->vm_next areas to the core file.
1574 */
1575
1576 /* alloc memory for large data structures: too large to be on stack */
1577 elf = kmalloc(sizeof(*elf), GFP_KERNEL);
1578 if (!elf)
1579 goto cleanup;
1580 prstatus = kzalloc(sizeof(*prstatus), GFP_KERNEL);
1581 if (!prstatus)
1582 goto cleanup;
1583 psinfo = kmalloc(sizeof(*psinfo), GFP_KERNEL);
1584 if (!psinfo)
1585 goto cleanup;
1586 notes = kmalloc(NUM_NOTES * sizeof(struct memelfnote), GFP_KERNEL);
1587 if (!notes)
1588 goto cleanup;
1589 fpu = kmalloc(sizeof(*fpu), GFP_KERNEL);
1590 if (!fpu)
1591 goto cleanup;
1592#ifdef ELF_CORE_COPY_XFPREGS
1593 xfpu = kmalloc(sizeof(*xfpu), GFP_KERNEL);
1594 if (!xfpu)
1595 goto cleanup;
1596#endif
1597
1598 if (signr) {
1599 struct elf_thread_status *tmp;
1600 read_lock(&tasklist_lock);
1601 do_each_thread(g,p)
1602 if (current->mm == p->mm && current != p) {
1603 tmp = kzalloc(sizeof(*tmp), GFP_ATOMIC);
1604 if (!tmp) {
1605 read_unlock(&tasklist_lock);
1606 goto cleanup;
1607 }
1608 INIT_LIST_HEAD(&tmp->list);
1609 tmp->thread = p;
1610 list_add(&tmp->list, &thread_list);
1611 }
1612 while_each_thread(g,p);
1613 read_unlock(&tasklist_lock);
1614 list_for_each(t, &thread_list) {
1615 struct elf_thread_status *tmp;
1616 int sz;
1617
1618 tmp = list_entry(t, struct elf_thread_status, list);
1619 sz = elf_dump_thread_status(signr, tmp);
1620 thread_status_size += sz;
1621 }
1622 }
1623
1624 /* now collect the dump for the current */
1625 fill_prstatus(prstatus, current, signr);
1626 elf_core_copy_regs(&prstatus->pr_reg, regs);
1627
1628#ifdef CONFIG_MMU
1629 segs = current->mm->map_count;
1630#else
1631 segs = 0;
1632 for (vml = current->mm->context.vmlist; vml; vml = vml->next)
1633 segs++;
1634#endif
1635#ifdef ELF_CORE_EXTRA_PHDRS
1636 segs += ELF_CORE_EXTRA_PHDRS;
1637#endif
1638
1639 /* Set up header */
1640 fill_elf_fdpic_header(elf, segs + 1); /* including notes section */
1641
1642 has_dumped = 1;
1643 current->flags |= PF_DUMPCORE;
1644
1645 /*
1646 * Set up the notes in similar form to SVR4 core dumps made
1647 * with info from their /proc.
1648 */
1649
1650 fill_note(notes + 0, "CORE", NT_PRSTATUS, sizeof(*prstatus), prstatus);
1651 fill_psinfo(psinfo, current->group_leader, current->mm);
1652 fill_note(notes + 1, "CORE", NT_PRPSINFO, sizeof(*psinfo), psinfo);
1653
1654 numnote = 2;
1655
1656 auxv = (elf_addr_t *) current->mm->saved_auxv;
1657
1658 i = 0;
1659 do
1660 i += 2;
1661 while (auxv[i - 2] != AT_NULL);
1662 fill_note(&notes[numnote++], "CORE", NT_AUXV,
1663 i * sizeof(elf_addr_t), auxv);
1664
1665 /* Try to dump the FPU. */
1666 if ((prstatus->pr_fpvalid =
1667 elf_core_copy_task_fpregs(current, regs, fpu)))
1668 fill_note(notes + numnote++,
1669 "CORE", NT_PRFPREG, sizeof(*fpu), fpu);
1670#ifdef ELF_CORE_COPY_XFPREGS
1671 if (elf_core_copy_task_xfpregs(current, xfpu))
1672 fill_note(notes + numnote++,
1673 "LINUX", NT_PRXFPREG, sizeof(*xfpu), xfpu);
1674#endif
1675
1676 fs = get_fs();
1677 set_fs(KERNEL_DS);
1678
1679 DUMP_WRITE(elf, sizeof(*elf));
1680 offset += sizeof(*elf); /* Elf header */
1681 offset += (segs+1) * sizeof(struct elf_phdr); /* Program headers */
1682
1683 /* Write notes phdr entry */
1684 {
1685 struct elf_phdr phdr;
1686 int sz = 0;
1687
1688 for (i = 0; i < numnote; i++)
1689 sz += notesize(notes + i);
1690
1691 sz += thread_status_size;
1692
1693 fill_elf_note_phdr(&phdr, sz, offset);
1694 offset += sz;
1695 DUMP_WRITE(&phdr, sizeof(phdr));
1696 }
1697
1698 /* Page-align dumped data */
1699 dataoff = offset = roundup(offset, ELF_EXEC_PAGESIZE);
1700
1701 /* write program headers for segments dump */
1702 for (
1703#ifdef CONFIG_MMU
1704 vma = current->mm->mmap; vma; vma = vma->vm_next
1705#else
1706 vml = current->mm->context.vmlist; vml; vml = vml->next
1707#endif
1708 ) {
1709 struct elf_phdr phdr;
1710 size_t sz;
1711
1712#ifndef CONFIG_MMU
1713 vma = vml->vma;
1714#endif
1715
1716 sz = vma->vm_end - vma->vm_start;
1717
1718 phdr.p_type = PT_LOAD;
1719 phdr.p_offset = offset;
1720 phdr.p_vaddr = vma->vm_start;
1721 phdr.p_paddr = 0;
1722 phdr.p_filesz = maydump(vma) ? sz : 0;
1723 phdr.p_memsz = sz;
1724 offset += phdr.p_filesz;
1725 phdr.p_flags = vma->vm_flags & VM_READ ? PF_R : 0;
1726 if (vma->vm_flags & VM_WRITE)
1727 phdr.p_flags |= PF_W;
1728 if (vma->vm_flags & VM_EXEC)
1729 phdr.p_flags |= PF_X;
1730 phdr.p_align = ELF_EXEC_PAGESIZE;
1731
1732 DUMP_WRITE(&phdr, sizeof(phdr));
1733 }
1734
1735#ifdef ELF_CORE_WRITE_EXTRA_PHDRS
1736 ELF_CORE_WRITE_EXTRA_PHDRS;
1737#endif
1738
1739 /* write out the notes section */
1740 for (i = 0; i < numnote; i++)
1741 if (!writenote(notes + i, file))
1742 goto end_coredump;
1743
1744 /* write out the thread status notes section */
1745 list_for_each(t, &thread_list) {
1746 struct elf_thread_status *tmp =
1747 list_entry(t, struct elf_thread_status, list);
1748
1749 for (i = 0; i < tmp->num_notes; i++)
1750 if (!writenote(&tmp->notes[i], file))
1751 goto end_coredump;
1752 }
1753
1754 DUMP_SEEK(dataoff);
1755
1756 if (elf_fdpic_dump_segments(file, current->mm, &size, &limit) < 0)
1757 goto end_coredump;
1758
1759#ifdef ELF_CORE_WRITE_EXTRA_DATA
1760 ELF_CORE_WRITE_EXTRA_DATA;
1761#endif
1762
1763 if (file->f_pos != offset) {
1764 /* Sanity check */
1765 printk(KERN_WARNING
1766 "elf_core_dump: file->f_pos (%lld) != offset (%lld)\n",
1767 file->f_pos, offset);
1768 }
1769
1770end_coredump:
1771 set_fs(fs);
1772
1773cleanup:
1774 while (!list_empty(&thread_list)) {
1775 struct list_head *tmp = thread_list.next;
1776 list_del(tmp);
1777 kfree(list_entry(tmp, struct elf_thread_status, list));
1778 }
1779
1780 kfree(elf);
1781 kfree(prstatus);
1782 kfree(psinfo);
1783 kfree(notes);
1784 kfree(fpu);
1785#ifdef ELF_CORE_COPY_XFPREGS
1786 kfree(xfpu);
1787#endif
1788 return has_dumped;
1789#undef NUM_NOTES
1790}
1791
1792#endif /* USE_ELF_CORE_DUMP */
diff --git a/fs/binfmt_flat.c b/fs/binfmt_flat.c
index c94d52eafd1b..a62fd4018a20 100644
--- a/fs/binfmt_flat.c
+++ b/fs/binfmt_flat.c
@@ -16,7 +16,6 @@
16 */ 16 */
17 17
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/config.h>
20#include <linux/kernel.h> 19#include <linux/kernel.h>
21#include <linux/sched.h> 20#include <linux/sched.h>
22#include <linux/mm.h> 21#include <linux/mm.h>
diff --git a/fs/binfmt_som.c b/fs/binfmt_som.c
index 00a91dc25d16..32b5d625ce9c 100644
--- a/fs/binfmt_som.c
+++ b/fs/binfmt_som.c
@@ -32,7 +32,6 @@
32#include <asm/uaccess.h> 32#include <asm/uaccess.h>
33#include <asm/pgtable.h> 33#include <asm/pgtable.h>
34 34
35#include <linux/config.h>
36 35
37#include <linux/elf.h> 36#include <linux/elf.h>
38 37
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 028d9fb9c2d5..37534573960b 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -5,14 +5,12 @@
5 * Copyright (C) 2001 Andrea Arcangeli <andrea@suse.de> SuSE 5 * Copyright (C) 2001 Andrea Arcangeli <andrea@suse.de> SuSE
6 */ 6 */
7 7
8#include <linux/config.h>
9#include <linux/init.h> 8#include <linux/init.h>
10#include <linux/mm.h> 9#include <linux/mm.h>
11#include <linux/fcntl.h> 10#include <linux/fcntl.h>
12#include <linux/slab.h> 11#include <linux/slab.h>
13#include <linux/kmod.h> 12#include <linux/kmod.h>
14#include <linux/major.h> 13#include <linux/major.h>
15#include <linux/devfs_fs_kernel.h>
16#include <linux/smp_lock.h> 14#include <linux/smp_lock.h>
17#include <linux/highmem.h> 15#include <linux/highmem.h>
18#include <linux/blkdev.h> 16#include <linux/blkdev.h>
@@ -741,7 +739,7 @@ static int bd_claim_by_kobject(struct block_device *bdev, void *holder,
741 if (!bo) 739 if (!bo)
742 return -ENOMEM; 740 return -ENOMEM;
743 741
744 mutex_lock(&bdev->bd_mutex); 742 mutex_lock_nested(&bdev->bd_mutex, BD_MUTEX_PARTITION);
745 res = bd_claim(bdev, holder); 743 res = bd_claim(bdev, holder);
746 if (res || !add_bd_holder(bdev, bo)) 744 if (res || !add_bd_holder(bdev, bo))
747 free_bd_holder(bo); 745 free_bd_holder(bo);
@@ -766,7 +764,7 @@ static void bd_release_from_kobject(struct block_device *bdev,
766 if (!kobj) 764 if (!kobj)
767 return; 765 return;
768 766
769 mutex_lock(&bdev->bd_mutex); 767 mutex_lock_nested(&bdev->bd_mutex, BD_MUTEX_PARTITION);
770 bd_release(bdev); 768 bd_release(bdev);
771 if ((bo = del_bd_holder(bdev, kobj))) 769 if ((bo = del_bd_holder(bdev, kobj)))
772 free_bd_holder(bo); 770 free_bd_holder(bo);
@@ -824,6 +822,22 @@ struct block_device *open_by_devnum(dev_t dev, unsigned mode)
824 822
825EXPORT_SYMBOL(open_by_devnum); 823EXPORT_SYMBOL(open_by_devnum);
826 824
825static int
826blkdev_get_partition(struct block_device *bdev, mode_t mode, unsigned flags);
827
828struct block_device *open_partition_by_devnum(dev_t dev, unsigned mode)
829{
830 struct block_device *bdev = bdget(dev);
831 int err = -ENOMEM;
832 int flags = mode & FMODE_WRITE ? O_RDWR : O_RDONLY;
833 if (bdev)
834 err = blkdev_get_partition(bdev, mode, flags);
835 return err ? ERR_PTR(err) : bdev;
836}
837
838EXPORT_SYMBOL(open_partition_by_devnum);
839
840
827/* 841/*
828 * This routine checks whether a removable media has been changed, 842 * This routine checks whether a removable media has been changed,
829 * and invalidates all buffer-cache-entries in that case. This 843 * and invalidates all buffer-cache-entries in that case. This
@@ -870,7 +884,11 @@ void bd_set_size(struct block_device *bdev, loff_t size)
870} 884}
871EXPORT_SYMBOL(bd_set_size); 885EXPORT_SYMBOL(bd_set_size);
872 886
873static int do_open(struct block_device *bdev, struct file *file) 887static int
888blkdev_get_whole(struct block_device *bdev, mode_t mode, unsigned flags);
889
890static int
891do_open(struct block_device *bdev, struct file *file, unsigned int subclass)
874{ 892{
875 struct module *owner = NULL; 893 struct module *owner = NULL;
876 struct gendisk *disk; 894 struct gendisk *disk;
@@ -887,7 +905,8 @@ static int do_open(struct block_device *bdev, struct file *file)
887 } 905 }
888 owner = disk->fops->owner; 906 owner = disk->fops->owner;
889 907
890 mutex_lock(&bdev->bd_mutex); 908 mutex_lock_nested(&bdev->bd_mutex, subclass);
909
891 if (!bdev->bd_openers) { 910 if (!bdev->bd_openers) {
892 bdev->bd_disk = disk; 911 bdev->bd_disk = disk;
893 bdev->bd_contains = bdev; 912 bdev->bd_contains = bdev;
@@ -914,11 +933,11 @@ static int do_open(struct block_device *bdev, struct file *file)
914 ret = -ENOMEM; 933 ret = -ENOMEM;
915 if (!whole) 934 if (!whole)
916 goto out_first; 935 goto out_first;
917 ret = blkdev_get(whole, file->f_mode, file->f_flags); 936 ret = blkdev_get_whole(whole, file->f_mode, file->f_flags);
918 if (ret) 937 if (ret)
919 goto out_first; 938 goto out_first;
920 bdev->bd_contains = whole; 939 bdev->bd_contains = whole;
921 mutex_lock(&whole->bd_mutex); 940 mutex_lock_nested(&whole->bd_mutex, BD_MUTEX_WHOLE);
922 whole->bd_part_count++; 941 whole->bd_part_count++;
923 p = disk->part[part - 1]; 942 p = disk->part[part - 1];
924 bdev->bd_inode->i_data.backing_dev_info = 943 bdev->bd_inode->i_data.backing_dev_info =
@@ -946,7 +965,8 @@ static int do_open(struct block_device *bdev, struct file *file)
946 if (bdev->bd_invalidated) 965 if (bdev->bd_invalidated)
947 rescan_partitions(bdev->bd_disk, bdev); 966 rescan_partitions(bdev->bd_disk, bdev);
948 } else { 967 } else {
949 mutex_lock(&bdev->bd_contains->bd_mutex); 968 mutex_lock_nested(&bdev->bd_contains->bd_mutex,
969 BD_MUTEX_PARTITION);
950 bdev->bd_contains->bd_part_count++; 970 bdev->bd_contains->bd_part_count++;
951 mutex_unlock(&bdev->bd_contains->bd_mutex); 971 mutex_unlock(&bdev->bd_contains->bd_mutex);
952 } 972 }
@@ -987,11 +1007,49 @@ int blkdev_get(struct block_device *bdev, mode_t mode, unsigned flags)
987 fake_file.f_dentry = &fake_dentry; 1007 fake_file.f_dentry = &fake_dentry;
988 fake_dentry.d_inode = bdev->bd_inode; 1008 fake_dentry.d_inode = bdev->bd_inode;
989 1009
990 return do_open(bdev, &fake_file); 1010 return do_open(bdev, &fake_file, BD_MUTEX_NORMAL);
991} 1011}
992 1012
993EXPORT_SYMBOL(blkdev_get); 1013EXPORT_SYMBOL(blkdev_get);
994 1014
1015static int
1016blkdev_get_whole(struct block_device *bdev, mode_t mode, unsigned flags)
1017{
1018 /*
1019 * This crockload is due to bad choice of ->open() type.
1020 * It will go away.
1021 * For now, block device ->open() routine must _not_
1022 * examine anything in 'inode' argument except ->i_rdev.
1023 */
1024 struct file fake_file = {};
1025 struct dentry fake_dentry = {};
1026 fake_file.f_mode = mode;
1027 fake_file.f_flags = flags;
1028 fake_file.f_dentry = &fake_dentry;
1029 fake_dentry.d_inode = bdev->bd_inode;
1030
1031 return do_open(bdev, &fake_file, BD_MUTEX_WHOLE);
1032}
1033
1034static int
1035blkdev_get_partition(struct block_device *bdev, mode_t mode, unsigned flags)
1036{
1037 /*
1038 * This crockload is due to bad choice of ->open() type.
1039 * It will go away.
1040 * For now, block device ->open() routine must _not_
1041 * examine anything in 'inode' argument except ->i_rdev.
1042 */
1043 struct file fake_file = {};
1044 struct dentry fake_dentry = {};
1045 fake_file.f_mode = mode;
1046 fake_file.f_flags = flags;
1047 fake_file.f_dentry = &fake_dentry;
1048 fake_dentry.d_inode = bdev->bd_inode;
1049
1050 return do_open(bdev, &fake_file, BD_MUTEX_PARTITION);
1051}
1052
995static int blkdev_open(struct inode * inode, struct file * filp) 1053static int blkdev_open(struct inode * inode, struct file * filp)
996{ 1054{
997 struct block_device *bdev; 1055 struct block_device *bdev;
@@ -1007,7 +1065,7 @@ static int blkdev_open(struct inode * inode, struct file * filp)
1007 1065
1008 bdev = bd_acquire(inode); 1066 bdev = bd_acquire(inode);
1009 1067
1010 res = do_open(bdev, filp); 1068 res = do_open(bdev, filp, BD_MUTEX_NORMAL);
1011 if (res) 1069 if (res)
1012 return res; 1070 return res;
1013 1071
@@ -1021,13 +1079,13 @@ static int blkdev_open(struct inode * inode, struct file * filp)
1021 return res; 1079 return res;
1022} 1080}
1023 1081
1024int blkdev_put(struct block_device *bdev) 1082static int __blkdev_put(struct block_device *bdev, unsigned int subclass)
1025{ 1083{
1026 int ret = 0; 1084 int ret = 0;
1027 struct inode *bd_inode = bdev->bd_inode; 1085 struct inode *bd_inode = bdev->bd_inode;
1028 struct gendisk *disk = bdev->bd_disk; 1086 struct gendisk *disk = bdev->bd_disk;
1029 1087
1030 mutex_lock(&bdev->bd_mutex); 1088 mutex_lock_nested(&bdev->bd_mutex, subclass);
1031 lock_kernel(); 1089 lock_kernel();
1032 if (!--bdev->bd_openers) { 1090 if (!--bdev->bd_openers) {
1033 sync_blockdev(bdev); 1091 sync_blockdev(bdev);
@@ -1037,7 +1095,8 @@ int blkdev_put(struct block_device *bdev)
1037 if (disk->fops->release) 1095 if (disk->fops->release)
1038 ret = disk->fops->release(bd_inode, NULL); 1096 ret = disk->fops->release(bd_inode, NULL);
1039 } else { 1097 } else {
1040 mutex_lock(&bdev->bd_contains->bd_mutex); 1098 mutex_lock_nested(&bdev->bd_contains->bd_mutex,
1099 subclass + 1);
1041 bdev->bd_contains->bd_part_count--; 1100 bdev->bd_contains->bd_part_count--;
1042 mutex_unlock(&bdev->bd_contains->bd_mutex); 1101 mutex_unlock(&bdev->bd_contains->bd_mutex);
1043 } 1102 }
@@ -1053,9 +1112,8 @@ int blkdev_put(struct block_device *bdev)
1053 } 1112 }
1054 bdev->bd_disk = NULL; 1113 bdev->bd_disk = NULL;
1055 bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info; 1114 bdev->bd_inode->i_data.backing_dev_info = &default_backing_dev_info;
1056 if (bdev != bdev->bd_contains) { 1115 if (bdev != bdev->bd_contains)
1057 blkdev_put(bdev->bd_contains); 1116 __blkdev_put(bdev->bd_contains, subclass + 1);
1058 }
1059 bdev->bd_contains = NULL; 1117 bdev->bd_contains = NULL;
1060 } 1118 }
1061 unlock_kernel(); 1119 unlock_kernel();
@@ -1064,8 +1122,20 @@ int blkdev_put(struct block_device *bdev)
1064 return ret; 1122 return ret;
1065} 1123}
1066 1124
1125int blkdev_put(struct block_device *bdev)
1126{
1127 return __blkdev_put(bdev, BD_MUTEX_NORMAL);
1128}
1129
1067EXPORT_SYMBOL(blkdev_put); 1130EXPORT_SYMBOL(blkdev_put);
1068 1131
1132int blkdev_put_partition(struct block_device *bdev)
1133{
1134 return __blkdev_put(bdev, BD_MUTEX_PARTITION);
1135}
1136
1137EXPORT_SYMBOL(blkdev_put_partition);
1138
1069static int blkdev_close(struct inode * inode, struct file * filp) 1139static int blkdev_close(struct inode * inode, struct file * filp)
1070{ 1140{
1071 struct block_device *bdev = I_BDEV(filp->f_mapping->host); 1141 struct block_device *bdev = I_BDEV(filp->f_mapping->host);
@@ -1095,7 +1165,7 @@ static long block_ioctl(struct file *file, unsigned cmd, unsigned long arg)
1095 return blkdev_ioctl(file->f_mapping->host, file, cmd, arg); 1165 return blkdev_ioctl(file->f_mapping->host, file, cmd, arg);
1096} 1166}
1097 1167
1098struct address_space_operations def_blk_aops = { 1168const struct address_space_operations def_blk_aops = {
1099 .readpage = blkdev_readpage, 1169 .readpage = blkdev_readpage,
1100 .writepage = blkdev_writepage, 1170 .writepage = blkdev_writepage,
1101 .sync_page = block_sync_page, 1171 .sync_page = block_sync_page,
diff --git a/fs/buffer.c b/fs/buffer.c
index f23bb647db47..3660dcb97591 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -18,7 +18,6 @@
18 * async buffer flushing, 1999 Andrea Arcangeli <andrea@suse.de> 18 * async buffer flushing, 1999 Andrea Arcangeli <andrea@suse.de>
19 */ 19 */
20 20
21#include <linux/config.h>
22#include <linux/kernel.h> 21#include <linux/kernel.h>
23#include <linux/syscalls.h> 22#include <linux/syscalls.h>
24#include <linux/fs.h> 23#include <linux/fs.h>
@@ -852,7 +851,7 @@ int __set_page_dirty_buffers(struct page *page)
852 write_lock_irq(&mapping->tree_lock); 851 write_lock_irq(&mapping->tree_lock);
853 if (page->mapping) { /* Race with truncate? */ 852 if (page->mapping) { /* Race with truncate? */
854 if (mapping_cap_account_dirty(mapping)) 853 if (mapping_cap_account_dirty(mapping))
855 inc_page_state(nr_dirty); 854 __inc_zone_page_state(page, NR_FILE_DIRTY);
856 radix_tree_tag_set(&mapping->page_tree, 855 radix_tree_tag_set(&mapping->page_tree,
857 page_index(page), 856 page_index(page),
858 PAGECACHE_TAG_DIRTY); 857 PAGECACHE_TAG_DIRTY);
@@ -2598,7 +2597,7 @@ int nobh_truncate_page(struct address_space *mapping, loff_t from)
2598 unsigned offset = from & (PAGE_CACHE_SIZE-1); 2597 unsigned offset = from & (PAGE_CACHE_SIZE-1);
2599 unsigned to; 2598 unsigned to;
2600 struct page *page; 2599 struct page *page;
2601 struct address_space_operations *a_ops = mapping->a_ops; 2600 const struct address_space_operations *a_ops = mapping->a_ops;
2602 char *kaddr; 2601 char *kaddr;
2603 int ret = 0; 2602 int ret = 0;
2604 2603
diff --git a/fs/char_dev.c b/fs/char_dev.c
index f3418f7a6e9d..a4cbc6706ef0 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -4,7 +4,6 @@
4 * Copyright (C) 1991, 1992 Linus Torvalds 4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */ 5 */
6 6
7#include <linux/config.h>
8#include <linux/init.h> 7#include <linux/init.h>
9#include <linux/fs.h> 8#include <linux/fs.h>
10#include <linux/slab.h> 9#include <linux/slab.h>
@@ -14,7 +13,6 @@
14#include <linux/errno.h> 13#include <linux/errno.h>
15#include <linux/module.h> 14#include <linux/module.h>
16#include <linux/smp_lock.h> 15#include <linux/smp_lock.h>
17#include <linux/devfs_fs_kernel.h>
18#include <linux/seq_file.h> 16#include <linux/seq_file.h>
19 17
20#include <linux/kobject.h> 18#include <linux/kobject.h>
diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c
index 031cdf293256..2e75883b7f54 100644
--- a/fs/cifs/asn1.c
+++ b/fs/cifs/asn1.c
@@ -17,7 +17,6 @@
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */ 18 */
19 19
20#include <linux/config.h>
21#include <linux/module.h> 20#include <linux/module.h>
22#include <linux/types.h> 21#include <linux/types.h>
23#include <linux/kernel.h> 22#include <linux/kernel.h>
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index a6384d83fdef..8f75c6f24701 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -32,8 +32,8 @@
32#define TRUE 1 32#define TRUE 1
33#endif 33#endif
34 34
35extern struct address_space_operations cifs_addr_ops; 35extern const struct address_space_operations cifs_addr_ops;
36extern struct address_space_operations cifs_addr_ops_smallbuf; 36extern const struct address_space_operations cifs_addr_ops_smallbuf;
37 37
38/* Functions related to super block operations */ 38/* Functions related to super block operations */
39extern struct super_operations cifs_super_ops; 39extern struct super_operations cifs_super_ops;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index e9c1573f6aa7..944d2b9e092d 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -324,7 +324,7 @@ out:
324 return rc; 324 return rc;
325} 325}
326 326
327/* Try to reaquire byte range locks that were released when session */ 327/* Try to reacquire byte range locks that were released when session */
328/* to server was lost */ 328/* to server was lost */
329static int cifs_relock_file(struct cifsFileInfo *cifsFile) 329static int cifs_relock_file(struct cifsFileInfo *cifsFile)
330{ 330{
@@ -1942,7 +1942,7 @@ static int cifs_prepare_write(struct file *file, struct page *page,
1942 return 0; 1942 return 0;
1943} 1943}
1944 1944
1945struct address_space_operations cifs_addr_ops = { 1945const struct address_space_operations cifs_addr_ops = {
1946 .readpage = cifs_readpage, 1946 .readpage = cifs_readpage,
1947 .readpages = cifs_readpages, 1947 .readpages = cifs_readpages,
1948 .writepage = cifs_writepage, 1948 .writepage = cifs_writepage,
@@ -1959,7 +1959,7 @@ struct address_space_operations cifs_addr_ops = {
1959 * contain the header plus one complete page of data. Otherwise, we need 1959 * contain the header plus one complete page of data. Otherwise, we need
1960 * to leave cifs_readpages out of the address space operations. 1960 * to leave cifs_readpages out of the address space operations.
1961 */ 1961 */
1962struct address_space_operations cifs_addr_ops_smallbuf = { 1962const struct address_space_operations cifs_addr_ops_smallbuf = {
1963 .readpage = cifs_readpage, 1963 .readpage = cifs_readpage,
1964 .writepage = cifs_writepage, 1964 .writepage = cifs_writepage,
1965 .writepages = cifs_writepages, 1965 .writepages = cifs_writepages,
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c
index 7caee8d8ea3b..803aacf0d49c 100644
--- a/fs/coda/psdev.c
+++ b/fs/coda/psdev.c
@@ -28,7 +28,6 @@
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/skbuff.h> 29#include <linux/skbuff.h>
30#include <linux/proc_fs.h> 30#include <linux/proc_fs.h>
31#include <linux/devfs_fs_kernel.h>
32#include <linux/vmalloc.h> 31#include <linux/vmalloc.h>
33#include <linux/fs.h> 32#include <linux/fs.h>
34#include <linux/file.h> 33#include <linux/file.h>
@@ -365,22 +364,12 @@ static int init_coda_psdev(void)
365 err = PTR_ERR(coda_psdev_class); 364 err = PTR_ERR(coda_psdev_class);
366 goto out_chrdev; 365 goto out_chrdev;
367 } 366 }
368 devfs_mk_dir ("coda"); 367 for (i = 0; i < MAX_CODADEVS; i++)
369 for (i = 0; i < MAX_CODADEVS; i++) {
370 class_device_create(coda_psdev_class, NULL, 368 class_device_create(coda_psdev_class, NULL,
371 MKDEV(CODA_PSDEV_MAJOR,i), NULL, "cfs%d", i); 369 MKDEV(CODA_PSDEV_MAJOR,i), NULL, "cfs%d", i);
372 err = devfs_mk_cdev(MKDEV(CODA_PSDEV_MAJOR, i),
373 S_IFCHR|S_IRUSR|S_IWUSR, "coda/%d", i);
374 if (err)
375 goto out_class;
376 }
377 coda_sysctl_init(); 370 coda_sysctl_init();
378 goto out; 371 goto out;
379 372
380out_class:
381 for (i = 0; i < MAX_CODADEVS; i++)
382 class_device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i));
383 class_destroy(coda_psdev_class);
384out_chrdev: 373out_chrdev:
385 unregister_chrdev(CODA_PSDEV_MAJOR, "coda"); 374 unregister_chrdev(CODA_PSDEV_MAJOR, "coda");
386out: 375out:
@@ -419,12 +408,9 @@ static int __init init_coda(void)
419 } 408 }
420 return 0; 409 return 0;
421out: 410out:
422 for (i = 0; i < MAX_CODADEVS; i++) { 411 for (i = 0; i < MAX_CODADEVS; i++)
423 class_device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i)); 412 class_device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i));
424 devfs_remove("coda/%d", i);
425 }
426 class_destroy(coda_psdev_class); 413 class_destroy(coda_psdev_class);
427 devfs_remove("coda");
428 unregister_chrdev(CODA_PSDEV_MAJOR, "coda"); 414 unregister_chrdev(CODA_PSDEV_MAJOR, "coda");
429 coda_sysctl_clean(); 415 coda_sysctl_clean();
430out1: 416out1:
@@ -441,12 +427,9 @@ static void __exit exit_coda(void)
441 if ( err != 0 ) { 427 if ( err != 0 ) {
442 printk("coda: failed to unregister filesystem\n"); 428 printk("coda: failed to unregister filesystem\n");
443 } 429 }
444 for (i = 0; i < MAX_CODADEVS; i++) { 430 for (i = 0; i < MAX_CODADEVS; i++)
445 class_device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i)); 431 class_device_destroy(coda_psdev_class, MKDEV(CODA_PSDEV_MAJOR, i));
446 devfs_remove("coda/%d", i);
447 }
448 class_destroy(coda_psdev_class); 432 class_destroy(coda_psdev_class);
449 devfs_remove("coda");
450 unregister_chrdev(CODA_PSDEV_MAJOR, "coda"); 433 unregister_chrdev(CODA_PSDEV_MAJOR, "coda");
451 coda_sysctl_clean(); 434 coda_sysctl_clean();
452 coda_destroy_inodecache(); 435 coda_destroy_inodecache();
diff --git a/fs/coda/symlink.c b/fs/coda/symlink.c
index b35e5bbd9c99..76e00a65a75b 100644
--- a/fs/coda/symlink.c
+++ b/fs/coda/symlink.c
@@ -50,6 +50,6 @@ fail:
50 return error; 50 return error;
51} 51}
52 52
53struct address_space_operations coda_symlink_aops = { 53const struct address_space_operations coda_symlink_aops = {
54 .readpage = coda_symlink_filler, 54 .readpage = coda_symlink_filler,
55}; 55};
diff --git a/fs/coda/sysctl.c b/fs/coda/sysctl.c
index f0b10757288f..1c82e9a7d7c8 100644
--- a/fs/coda/sysctl.c
+++ b/fs/coda/sysctl.c
@@ -11,7 +11,6 @@
11 * 11 *
12 */ 12 */
13 13
14#include <linux/config.h>
15#include <linux/time.h> 14#include <linux/time.h>
16#include <linux/mm.h> 15#include <linux/mm.h>
17#include <linux/sysctl.h> 16#include <linux/sysctl.h>
diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
index d8ecfedef189..4063a9396977 100644
--- a/fs/compat_ioctl.c
+++ b/fs/compat_ioctl.c
@@ -10,7 +10,6 @@
10 * ioctls. 10 * ioctls.
11 */ 11 */
12 12
13#include <linux/config.h>
14#include <linux/types.h> 13#include <linux/types.h>
15#include <linux/compat.h> 14#include <linux/compat.h>
16#include <linux/kernel.h> 15#include <linux/kernel.h>
@@ -44,7 +43,6 @@
44#include <linux/loop.h> 43#include <linux/loop.h>
45#include <linux/auto_fs.h> 44#include <linux/auto_fs.h>
46#include <linux/auto_fs4.h> 45#include <linux/auto_fs4.h>
47#include <linux/devfs_fs.h>
48#include <linux/tty.h> 46#include <linux/tty.h>
49#include <linux/vt_kern.h> 47#include <linux/vt_kern.h>
50#include <linux/fb.h> 48#include <linux/fb.h>
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
index 207f8006fd6c..df025453dd97 100644
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -211,7 +211,7 @@ static void remove_dir(struct dentry * d)
211 struct configfs_dirent * sd; 211 struct configfs_dirent * sd;
212 212
213 sd = d->d_fsdata; 213 sd = d->d_fsdata;
214 list_del_init(&sd->s_sibling); 214 list_del_init(&sd->s_sibling);
215 configfs_put(sd); 215 configfs_put(sd);
216 if (d->d_inode) 216 if (d->d_inode)
217 simple_rmdir(parent->d_inode,d); 217 simple_rmdir(parent->d_inode,d);
@@ -330,7 +330,7 @@ static int configfs_detach_prep(struct dentry *dentry)
330 330
331 ret = configfs_detach_prep(sd->s_dentry); 331 ret = configfs_detach_prep(sd->s_dentry);
332 if (!ret) 332 if (!ret)
333 continue; 333 continue;
334 } else 334 } else
335 ret = -ENOTEMPTY; 335 ret = -ENOTEMPTY;
336 336
@@ -931,7 +931,7 @@ int configfs_rename_dir(struct config_item * item, const char *new_name)
931 931
932 new_dentry = lookup_one_len(new_name, parent, strlen(new_name)); 932 new_dentry = lookup_one_len(new_name, parent, strlen(new_name));
933 if (!IS_ERR(new_dentry)) { 933 if (!IS_ERR(new_dentry)) {
934 if (!new_dentry->d_inode) { 934 if (!new_dentry->d_inode) {
935 error = config_item_set_name(item, "%s", new_name); 935 error = config_item_set_name(item, "%s", new_name);
936 if (!error) { 936 if (!error) {
937 d_add(new_dentry, NULL); 937 d_add(new_dentry, NULL);
diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c
index c153bd9534cb..e14488ca6411 100644
--- a/fs/configfs/inode.c
+++ b/fs/configfs/inode.c
@@ -38,7 +38,7 @@
38 38
39extern struct super_block * configfs_sb; 39extern struct super_block * configfs_sb;
40 40
41static struct address_space_operations configfs_aops = { 41static const struct address_space_operations configfs_aops = {
42 .readpage = simple_readpage, 42 .readpage = simple_readpage,
43 .prepare_write = simple_prepare_write, 43 .prepare_write = simple_prepare_write,
44 .commit_write = simple_commit_write 44 .commit_write = simple_commit_write
diff --git a/fs/configfs/symlink.c b/fs/configfs/symlink.c
index e5512e295cf2..fb65e0800a86 100644
--- a/fs/configfs/symlink.c
+++ b/fs/configfs/symlink.c
@@ -66,7 +66,7 @@ static void fill_item_path(struct config_item * item, char * buffer, int length)
66} 66}
67 67
68static int create_link(struct config_item *parent_item, 68static int create_link(struct config_item *parent_item,
69 struct config_item *item, 69 struct config_item *item,
70 struct dentry *dentry) 70 struct dentry *dentry)
71{ 71{
72 struct configfs_dirent *target_sd = item->ci_dentry->d_fsdata; 72 struct configfs_dirent *target_sd = item->ci_dentry->d_fsdata;
diff --git a/fs/cramfs/inode.c b/fs/cramfs/inode.c
index c45d73860803..223c0431042d 100644
--- a/fs/cramfs/inode.c
+++ b/fs/cramfs/inode.c
@@ -30,7 +30,7 @@
30static struct super_operations cramfs_ops; 30static struct super_operations cramfs_ops;
31static struct inode_operations cramfs_dir_inode_operations; 31static struct inode_operations cramfs_dir_inode_operations;
32static const struct file_operations cramfs_directory_operations; 32static const struct file_operations cramfs_directory_operations;
33static struct address_space_operations cramfs_aops; 33static const struct address_space_operations cramfs_aops;
34 34
35static DEFINE_MUTEX(read_mutex); 35static DEFINE_MUTEX(read_mutex);
36 36
@@ -501,7 +501,7 @@ static int cramfs_readpage(struct file *file, struct page * page)
501 return 0; 501 return 0;
502} 502}
503 503
504static struct address_space_operations cramfs_aops = { 504static const struct address_space_operations cramfs_aops = {
505 .readpage = cramfs_readpage 505 .readpage = cramfs_readpage
506}; 506};
507 507
diff --git a/fs/dcache.c b/fs/dcache.c
index 48b44a714b35..1b4a3a34ec57 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -14,7 +14,6 @@
14 * the dcache entry is deleted or garbage collected. 14 * the dcache entry is deleted or garbage collected.
15 */ 15 */
16 16
17#include <linux/config.h>
18#include <linux/syscalls.h> 17#include <linux/syscalls.h>
19#include <linux/string.h> 18#include <linux/string.h>
20#include <linux/mm.h> 19#include <linux/mm.h>
@@ -39,7 +38,7 @@ int sysctl_vfs_cache_pressure __read_mostly = 100;
39EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure); 38EXPORT_SYMBOL_GPL(sysctl_vfs_cache_pressure);
40 39
41 __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lock); 40 __cacheline_aligned_in_smp DEFINE_SPINLOCK(dcache_lock);
42static seqlock_t rename_lock __cacheline_aligned_in_smp = SEQLOCK_UNLOCKED; 41static __cacheline_aligned_in_smp DEFINE_SEQLOCK(rename_lock);
43 42
44EXPORT_SYMBOL(dcache_lock); 43EXPORT_SYMBOL(dcache_lock);
45 44
@@ -1340,10 +1339,10 @@ void d_move(struct dentry * dentry, struct dentry * target)
1340 */ 1339 */
1341 if (target < dentry) { 1340 if (target < dentry) {
1342 spin_lock(&target->d_lock); 1341 spin_lock(&target->d_lock);
1343 spin_lock(&dentry->d_lock); 1342 spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED);
1344 } else { 1343 } else {
1345 spin_lock(&dentry->d_lock); 1344 spin_lock(&dentry->d_lock);
1346 spin_lock(&target->d_lock); 1345 spin_lock_nested(&target->d_lock, DENTRY_D_LOCK_NESTED);
1347 } 1346 }
1348 1347
1349 /* Move the dentry to the target hash queue, if on different bucket */ 1348 /* Move the dentry to the target hash queue, if on different bucket */
diff --git a/fs/dcookies.c b/fs/dcookies.c
index 8749339bf4f6..0c4b0674854b 100644
--- a/fs/dcookies.c
+++ b/fs/dcookies.c
@@ -12,7 +12,6 @@
12 * to the pair and can be looked up from userspace. 12 * to the pair and can be looked up from userspace.
13 */ 13 */
14 14
15#include <linux/config.h>
16#include <linux/syscalls.h> 15#include <linux/syscalls.h>
17#include <linux/module.h> 16#include <linux/module.h>
18#include <linux/slab.h> 17#include <linux/slab.h>
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index 66a505422e5c..39640fd03458 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -13,7 +13,6 @@
13 * 13 *
14 */ 14 */
15 15
16#include <linux/config.h>
17#include <linux/module.h> 16#include <linux/module.h>
18#include <linux/fs.h> 17#include <linux/fs.h>
19#include <linux/pagemap.h> 18#include <linux/pagemap.h>
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index 6fa1e04f8415..e8ae3042b806 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -16,7 +16,6 @@
16/* uncomment to get debug messages from the debug filesystem, ah the irony. */ 16/* uncomment to get debug messages from the debug filesystem, ah the irony. */
17/* #define DEBUG */ 17/* #define DEBUG */
18 18
19#include <linux/config.h>
20#include <linux/module.h> 19#include <linux/module.h>
21#include <linux/fs.h> 20#include <linux/fs.h>
22#include <linux/mount.h> 21#include <linux/mount.h>
diff --git a/fs/devfs/Makefile b/fs/devfs/Makefile
deleted file mode 100644
index 6dd8d1245e2c..000000000000
--- a/fs/devfs/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
1#
2# Makefile for the linux devfs-filesystem routines.
3#
4
5obj-$(CONFIG_DEVFS_FS) += devfs.o
6
7devfs-objs := base.o util.o
8
diff --git a/fs/devfs/base.c b/fs/devfs/base.c
deleted file mode 100644
index 51a97f132745..000000000000
--- a/fs/devfs/base.c
+++ /dev/null
@@ -1,2836 +0,0 @@
1/* devfs (Device FileSystem) driver.
2
3 Copyright (C) 1998-2002 Richard Gooch
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free
17 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19 Richard Gooch may be reached by email at rgooch@atnf.csiro.au
20 The postal address is:
21 Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
22
23 ChangeLog
24
25 19980110 Richard Gooch <rgooch@atnf.csiro.au>
26 Original version.
27 v0.1
28 19980111 Richard Gooch <rgooch@atnf.csiro.au>
29 Created per-fs inode table rather than using inode->u.generic_ip
30 v0.2
31 19980111 Richard Gooch <rgooch@atnf.csiro.au>
32 Created .epoch inode which has a ctime of 0.
33 Fixed loss of named pipes when dentries lost.
34 Fixed loss of inode data when devfs_register() follows mknod().
35 v0.3
36 19980111 Richard Gooch <rgooch@atnf.csiro.au>
37 Fix for when compiling with CONFIG_KERNELD.
38 19980112 Richard Gooch <rgooch@atnf.csiro.au>
39 Fix for readdir() which sometimes didn't show entries.
40 Added <<tolerant>> option to <devfs_register>.
41 v0.4
42 19980113 Richard Gooch <rgooch@atnf.csiro.au>
43 Created <devfs_fill_file> function.
44 v0.5
45 19980115 Richard Gooch <rgooch@atnf.csiro.au>
46 Added subdirectory support. Major restructuring.
47 19980116 Richard Gooch <rgooch@atnf.csiro.au>
48 Fixed <find_by_dev> to not search major=0,minor=0.
49 Added symlink support.
50 v0.6
51 19980120 Richard Gooch <rgooch@atnf.csiro.au>
52 Created <devfs_mk_dir> function and support directory unregister
53 19980120 Richard Gooch <rgooch@atnf.csiro.au>
54 Auto-ownership uses real uid/gid rather than effective uid/gid.
55 v0.7
56 19980121 Richard Gooch <rgooch@atnf.csiro.au>
57 Supported creation of sockets.
58 v0.8
59 19980122 Richard Gooch <rgooch@atnf.csiro.au>
60 Added DEVFS_FL_HIDE_UNREG flag.
61 Interface change to <devfs_mk_symlink>.
62 Created <devfs_symlink> to support symlink(2).
63 v0.9
64 19980123 Richard Gooch <rgooch@atnf.csiro.au>
65 Added check to <devfs_fill_file> to check inode is in devfs.
66 Added optional traversal of symlinks.
67 v0.10
68 19980124 Richard Gooch <rgooch@atnf.csiro.au>
69 Created <devfs_get_flags> and <devfs_set_flags>.
70 v0.11
71 19980125 C. Scott Ananian <cananian@alumni.princeton.edu>
72 Created <devfs_find_handle>.
73 19980125 Richard Gooch <rgooch@atnf.csiro.au>
74 Allow removal of symlinks.
75 v0.12
76 19980125 Richard Gooch <rgooch@atnf.csiro.au>
77 Created <devfs_set_symlink_destination>.
78 19980126 Richard Gooch <rgooch@atnf.csiro.au>
79 Moved DEVFS_SUPER_MAGIC into header file.
80 Added DEVFS_FL_HIDE flag.
81 Created <devfs_get_maj_min>.
82 Created <devfs_get_handle_from_inode>.
83 Fixed minor bug in <find_by_dev>.
84 19980127 Richard Gooch <rgooch@atnf.csiro.au>
85 Changed interface to <find_by_dev>, <find_entry>,
86 <devfs_unregister>, <devfs_fill_file> and <devfs_find_handle>.
87 Fixed inode times when symlink created with symlink(2).
88 v0.13
89 19980129 C. Scott Ananian <cananian@alumni.princeton.edu>
90 Exported <devfs_set_symlink_destination>, <devfs_get_maj_min>
91 and <devfs_get_handle_from_inode>.
92 19980129 Richard Gooch <rgooch@atnf.csiro.au>
93 Created <devfs_unlink> to support unlink(2).
94 v0.14
95 19980129 Richard Gooch <rgooch@atnf.csiro.au>
96 Fixed kerneld support for entries in devfs subdirectories.
97 19980130 Richard Gooch <rgooch@atnf.csiro.au>
98 Bugfixes in <call_kerneld>.
99 v0.15
100 19980207 Richard Gooch <rgooch@atnf.csiro.au>
101 Call kerneld when looking up unregistered entries.
102 v0.16
103 19980326 Richard Gooch <rgooch@atnf.csiro.au>
104 Modified interface to <devfs_find_handle> for symlink traversal.
105 v0.17
106 19980331 Richard Gooch <rgooch@atnf.csiro.au>
107 Fixed persistence bug with device numbers for manually created
108 device files.
109 Fixed problem with recreating symlinks with different content.
110 v0.18
111 19980401 Richard Gooch <rgooch@atnf.csiro.au>
112 Changed to CONFIG_KMOD.
113 Hide entries which are manually unlinked.
114 Always invalidate devfs dentry cache when registering entries.
115 Created <devfs_rmdir> to support rmdir(2).
116 Ensure directories created by <devfs_mk_dir> are visible.
117 v0.19
118 19980402 Richard Gooch <rgooch@atnf.csiro.au>
119 Invalidate devfs dentry cache when making directories.
120 Invalidate devfs dentry cache when removing entries.
121 Fixed persistence bug with fifos.
122 v0.20
123 19980421 Richard Gooch <rgooch@atnf.csiro.au>
124 Print process command when debugging kerneld/kmod.
125 Added debugging for register/unregister/change operations.
126 19980422 Richard Gooch <rgooch@atnf.csiro.au>
127 Added "devfs=" boot options.
128 v0.21
129 19980426 Richard Gooch <rgooch@atnf.csiro.au>
130 No longer lock/unlock superblock in <devfs_put_super>.
131 Drop negative dentries when they are released.
132 Manage dcache more efficiently.
133 v0.22
134 19980427 Richard Gooch <rgooch@atnf.csiro.au>
135 Added DEVFS_FL_AUTO_DEVNUM flag.
136 v0.23
137 19980430 Richard Gooch <rgooch@atnf.csiro.au>
138 No longer set unnecessary methods.
139 v0.24
140 19980504 Richard Gooch <rgooch@atnf.csiro.au>
141 Added PID display to <call_kerneld> debugging message.
142 Added "after" debugging message to <call_kerneld>.
143 19980519 Richard Gooch <rgooch@atnf.csiro.au>
144 Added "diread" and "diwrite" boot options.
145 19980520 Richard Gooch <rgooch@atnf.csiro.au>
146 Fixed persistence problem with permissions.
147 v0.25
148 19980602 Richard Gooch <rgooch@atnf.csiro.au>
149 Support legacy device nodes.
150 Fixed bug where recreated inodes were hidden.
151 v0.26
152 19980602 Richard Gooch <rgooch@atnf.csiro.au>
153 Improved debugging in <get_vfs_inode>.
154 19980607 Richard Gooch <rgooch@atnf.csiro.au>
155 No longer free old dentries in <devfs_mk_dir>.
156 Free all dentries for a given entry when deleting inodes.
157 v0.27
158 19980627 Richard Gooch <rgooch@atnf.csiro.au>
159 Limit auto-device numbering to majors 128 to 239.
160 v0.28
161 19980629 Richard Gooch <rgooch@atnf.csiro.au>
162 Fixed inode times persistence problem.
163 v0.29
164 19980704 Richard Gooch <rgooch@atnf.csiro.au>
165 Fixed spelling in <devfs_readlink> debug.
166 Fixed bug in <devfs_setup> parsing "dilookup".
167 v0.30
168 19980705 Richard Gooch <rgooch@atnf.csiro.au>
169 Fixed devfs inode leak when manually recreating inodes.
170 Fixed permission persistence problem when recreating inodes.
171 v0.31
172 19980727 Richard Gooch <rgooch@atnf.csiro.au>
173 Removed harmless "unused variable" compiler warning.
174 Fixed modes for manually recreated device nodes.
175 v0.32
176 19980728 Richard Gooch <rgooch@atnf.csiro.au>
177 Added NULL devfs inode warning in <devfs_read_inode>.
178 Force all inode nlink values to 1.
179 v0.33
180 19980730 Richard Gooch <rgooch@atnf.csiro.au>
181 Added "dimknod" boot option.
182 Set inode nlink to 0 when freeing dentries.
183 Fixed modes for manually recreated symlinks.
184 v0.34
185 19980802 Richard Gooch <rgooch@atnf.csiro.au>
186 Fixed bugs in recreated directories and symlinks.
187 v0.35
188 19980806 Richard Gooch <rgooch@atnf.csiro.au>
189 Fixed bugs in recreated device nodes.
190 19980807 Richard Gooch <rgooch@atnf.csiro.au>
191 Fixed bug in currently unused <devfs_get_handle_from_inode>.
192 Defined new <devfs_handle_t> type.
193 Improved debugging when getting entries.
194 Fixed bug where directories could be emptied.
195 v0.36
196 19980809 Richard Gooch <rgooch@atnf.csiro.au>
197 Replaced dummy .epoch inode with .devfsd character device.
198 19980810 Richard Gooch <rgooch@atnf.csiro.au>
199 Implemented devfsd protocol revision 0.
200 v0.37
201 19980819 Richard Gooch <rgooch@atnf.csiro.au>
202 Added soothing message to warning in <devfs_d_iput>.
203 v0.38
204 19980829 Richard Gooch <rgooch@atnf.csiro.au>
205 Use GCC extensions for structure initialisations.
206 Implemented async open notification.
207 Incremented devfsd protocol revision to 1.
208 v0.39
209 19980908 Richard Gooch <rgooch@atnf.csiro.au>
210 Moved async open notification to end of <devfs_open>.
211 v0.40
212 19980910 Richard Gooch <rgooch@atnf.csiro.au>
213 Prepended "/dev/" to module load request.
214 Renamed <call_kerneld> to <call_kmod>.
215 v0.41
216 19980910 Richard Gooch <rgooch@atnf.csiro.au>
217 Fixed typo "AYSNC" -> "ASYNC".
218 v0.42
219 19980910 Richard Gooch <rgooch@atnf.csiro.au>
220 Added open flag for files.
221 v0.43
222 19980927 Richard Gooch <rgooch@atnf.csiro.au>
223 Set i_blocks=0 and i_blksize=1024 in <devfs_read_inode>.
224 v0.44
225 19981005 Richard Gooch <rgooch@atnf.csiro.au>
226 Added test for empty <<name>> in <devfs_find_handle>.
227 Renamed <generate_path> to <devfs_generate_path> and published.
228 v0.45
229 19981006 Richard Gooch <rgooch@atnf.csiro.au>
230 Created <devfs_get_fops>.
231 v0.46
232 19981007 Richard Gooch <rgooch@atnf.csiro.au>
233 Limit auto-device numbering to majors 144 to 239.
234 v0.47
235 19981010 Richard Gooch <rgooch@atnf.csiro.au>
236 Updated <devfs_follow_link> for VFS change in 2.1.125.
237 v0.48
238 19981022 Richard Gooch <rgooch@atnf.csiro.au>
239 Created DEVFS_ FL_COMPAT flag.
240 v0.49
241 19981023 Richard Gooch <rgooch@atnf.csiro.au>
242 Created "nocompat" boot option.
243 v0.50
244 19981025 Richard Gooch <rgooch@atnf.csiro.au>
245 Replaced "mount" boot option with "nomount".
246 v0.51
247 19981110 Richard Gooch <rgooch@atnf.csiro.au>
248 Created "only" boot option.
249 v0.52
250 19981112 Richard Gooch <rgooch@atnf.csiro.au>
251 Added DEVFS_FL_REMOVABLE flag.
252 v0.53
253 19981114 Richard Gooch <rgooch@atnf.csiro.au>
254 Only call <scan_dir_for_removable> on first call to
255 <devfs_readdir>.
256 v0.54
257 19981205 Richard Gooch <rgooch@atnf.csiro.au>
258 Updated <devfs_rmdir> for VFS change in 2.1.131.
259 v0.55
260 19981218 Richard Gooch <rgooch@atnf.csiro.au>
261 Created <devfs_mk_compat>.
262 19981220 Richard Gooch <rgooch@atnf.csiro.au>
263 Check for partitions on removable media in <devfs_lookup>.
264 v0.56
265 19990118 Richard Gooch <rgooch@atnf.csiro.au>
266 Added support for registering regular files.
267 Created <devfs_set_file_size>.
268 Update devfs inodes from entries if not changed through FS.
269 v0.57
270 19990124 Richard Gooch <rgooch@atnf.csiro.au>
271 Fixed <devfs_fill_file> to only initialise temporary inodes.
272 Trap for NULL fops in <devfs_register>.
273 Return -ENODEV in <devfs_fill_file> for non-driver inodes.
274 v0.58
275 19990126 Richard Gooch <rgooch@atnf.csiro.au>
276 Switched from PATH_MAX to DEVFS_PATHLEN.
277 v0.59
278 19990127 Richard Gooch <rgooch@atnf.csiro.au>
279 Created "nottycompat" boot option.
280 v0.60
281 19990318 Richard Gooch <rgooch@atnf.csiro.au>
282 Fixed <devfsd_read> to not overrun event buffer.
283 v0.61
284 19990329 Richard Gooch <rgooch@atnf.csiro.au>
285 Created <devfs_auto_unregister>.
286 v0.62
287 19990330 Richard Gooch <rgooch@atnf.csiro.au>
288 Don't return unregistred entries in <devfs_find_handle>.
289 Panic in <devfs_unregister> if entry unregistered.
290 19990401 Richard Gooch <rgooch@atnf.csiro.au>
291 Don't panic in <devfs_auto_unregister> for duplicates.
292 v0.63
293 19990402 Richard Gooch <rgooch@atnf.csiro.au>
294 Don't unregister already unregistered entries in <unregister>.
295 v0.64
296 19990510 Richard Gooch <rgooch@atnf.csiro.au>
297 Disable warning messages when unable to read partition table for
298 removable media.
299 v0.65
300 19990512 Richard Gooch <rgooch@atnf.csiro.au>
301 Updated <devfs_lookup> for VFS change in 2.3.1-pre1.
302 Created "oops-on-panic" boot option.
303 Improved debugging in <devfs_register> and <devfs_unregister>.
304 v0.66
305 19990519 Richard Gooch <rgooch@atnf.csiro.au>
306 Added documentation for some functions.
307 19990525 Richard Gooch <rgooch@atnf.csiro.au>
308 Removed "oops-on-panic" boot option: now always Oops.
309 v0.67
310 19990531 Richard Gooch <rgooch@atnf.csiro.au>
311 Improved debugging in <devfs_register>.
312 v0.68
313 19990604 Richard Gooch <rgooch@atnf.csiro.au>
314 Added "diunlink" and "nokmod" boot options.
315 Removed superfluous warning message in <devfs_d_iput>.
316 v0.69
317 19990611 Richard Gooch <rgooch@atnf.csiro.au>
318 Took account of change to <d_alloc_root>.
319 v0.70
320 19990614 Richard Gooch <rgooch@atnf.csiro.au>
321 Created separate event queue for each mounted devfs.
322 Removed <devfs_invalidate_dcache>.
323 Created new ioctl()s.
324 Incremented devfsd protocol revision to 3.
325 Fixed bug when re-creating directories: contents were lost.
326 Block access to inodes until devfsd updates permissions.
327 19990615 Richard Gooch <rgooch@atnf.csiro.au>
328 Support 2.2.x kernels.
329 v0.71
330 19990623 Richard Gooch <rgooch@atnf.csiro.au>
331 Switched to sending process uid/gid to devfsd.
332 Renamed <call_kmod> to <try_modload>.
333 Added DEVFSD_NOTIFY_LOOKUP event.
334 19990624 Richard Gooch <rgooch@atnf.csiro.au>
335 Added DEVFSD_NOTIFY_CHANGE event.
336 Incremented devfsd protocol revision to 4.
337 v0.72
338 19990713 Richard Gooch <rgooch@atnf.csiro.au>
339 Return EISDIR rather than EINVAL for read(2) on directories.
340 v0.73
341 19990809 Richard Gooch <rgooch@atnf.csiro.au>
342 Changed <devfs_setup> to new __init scheme.
343 v0.74
344 19990901 Richard Gooch <rgooch@atnf.csiro.au>
345 Changed remaining function declarations to new __init scheme.
346 v0.75
347 19991013 Richard Gooch <rgooch@atnf.csiro.au>
348 Created <devfs_get_info>, <devfs_set_info>,
349 <devfs_get_first_child> and <devfs_get_next_sibling>.
350 Added <<dir>> parameter to <devfs_register>, <devfs_mk_compat>,
351 <devfs_mk_dir> and <devfs_find_handle>.
352 Work sponsored by SGI.
353 v0.76
354 19991017 Richard Gooch <rgooch@atnf.csiro.au>
355 Allow multiple unregistrations.
356 Work sponsored by SGI.
357 v0.77
358 19991026 Richard Gooch <rgooch@atnf.csiro.au>
359 Added major and minor number to devfsd protocol.
360 Incremented devfsd protocol revision to 5.
361 Work sponsored by SGI.
362 v0.78
363 19991030 Richard Gooch <rgooch@atnf.csiro.au>
364 Support info pointer for all devfs entry types.
365 Added <<info>> parameter to <devfs_mk_dir> and
366 <devfs_mk_symlink>.
367 Work sponsored by SGI.
368 v0.79
369 19991031 Richard Gooch <rgooch@atnf.csiro.au>
370 Support "../" when searching devfs namespace.
371 Work sponsored by SGI.
372 v0.80
373 19991101 Richard Gooch <rgooch@atnf.csiro.au>
374 Created <devfs_get_unregister_slave>.
375 Work sponsored by SGI.
376 v0.81
377 19991103 Richard Gooch <rgooch@atnf.csiro.au>
378 Exported <devfs_get_parent>.
379 Work sponsored by SGI.
380 v0.82
381 19991104 Richard Gooch <rgooch@atnf.csiro.au>
382 Removed unused <devfs_set_symlink_destination>.
383 19991105 Richard Gooch <rgooch@atnf.csiro.au>
384 Do not hide entries from devfsd or children.
385 Removed DEVFS_ FL_TTY_COMPAT flag.
386 Removed "nottycompat" boot option.
387 Removed <devfs_mk_compat>.
388 Work sponsored by SGI.
389 v0.83
390 19991107 Richard Gooch <rgooch@atnf.csiro.au>
391 Added DEVFS_FL_WAIT flag.
392 Work sponsored by SGI.
393 v0.84
394 19991107 Richard Gooch <rgooch@atnf.csiro.au>
395 Support new "disc" naming scheme in <get_removable_partition>.
396 Allow NULL fops in <devfs_register>.
397 Work sponsored by SGI.
398 v0.85
399 19991110 Richard Gooch <rgooch@atnf.csiro.au>
400 Fall back to major table if NULL fops given to <devfs_register>.
401 Work sponsored by SGI.
402 v0.86
403 19991204 Richard Gooch <rgooch@atnf.csiro.au>
404 Support fifos when unregistering.
405 Work sponsored by SGI.
406 v0.87
407 19991209 Richard Gooch <rgooch@atnf.csiro.au>
408 Removed obsolete DEVFS_ FL_COMPAT and DEVFS_ FL_TOLERANT flags.
409 Work sponsored by SGI.
410 v0.88
411 19991214 Richard Gooch <rgooch@atnf.csiro.au>
412 Removed kmod support.
413 Work sponsored by SGI.
414 v0.89
415 19991216 Richard Gooch <rgooch@atnf.csiro.au>
416 Improved debugging in <get_vfs_inode>.
417 Ensure dentries created by devfsd will be cleaned up.
418 Work sponsored by SGI.
419 v0.90
420 19991223 Richard Gooch <rgooch@atnf.csiro.au>
421 Created <devfs_get_name>.
422 Work sponsored by SGI.
423 v0.91
424 20000203 Richard Gooch <rgooch@atnf.csiro.au>
425 Ported to kernel 2.3.42.
426 Removed <devfs_fill_file>.
427 Work sponsored by SGI.
428 v0.92
429 20000306 Richard Gooch <rgooch@atnf.csiro.au>
430 Added DEVFS_ FL_NO_PERSISTENCE flag.
431 Removed unnecessary call to <update_devfs_inode_from_entry> in
432 <devfs_readdir>.
433 Work sponsored by SGI.
434 v0.93
435 20000413 Richard Gooch <rgooch@atnf.csiro.au>
436 Set inode->i_size to correct size for symlinks.
437 20000414 Richard Gooch <rgooch@atnf.csiro.au>
438 Only give lookup() method to directories to comply with new VFS
439 assumptions.
440 Work sponsored by SGI.
441 20000415 Richard Gooch <rgooch@atnf.csiro.au>
442 Remove unnecessary tests in symlink methods.
443 Don't kill existing block ops in <devfs_read_inode>.
444 Work sponsored by SGI.
445 v0.94
446 20000424 Richard Gooch <rgooch@atnf.csiro.au>
447 Don't create missing directories in <devfs_find_handle>.
448 Work sponsored by SGI.
449 v0.95
450 20000430 Richard Gooch <rgooch@atnf.csiro.au>
451 Added CONFIG_DEVFS_MOUNT.
452 Work sponsored by SGI.
453 v0.96
454 20000608 Richard Gooch <rgooch@atnf.csiro.au>
455 Disabled multi-mount capability (use VFS bindings instead).
456 Work sponsored by SGI.
457 v0.97
458 20000610 Richard Gooch <rgooch@atnf.csiro.au>
459 Switched to FS_SINGLE to disable multi-mounts.
460 20000612 Richard Gooch <rgooch@atnf.csiro.au>
461 Removed module support.
462 Removed multi-mount code.
463 Removed compatibility macros: VFS has changed too much.
464 Work sponsored by SGI.
465 v0.98
466 20000614 Richard Gooch <rgooch@atnf.csiro.au>
467 Merged devfs inode into devfs entry.
468 Work sponsored by SGI.
469 v0.99
470 20000619 Richard Gooch <rgooch@atnf.csiro.au>
471 Removed dead code in <devfs_register> which used to call
472 <free_dentries>.
473 Work sponsored by SGI.
474 v0.100
475 20000621 Richard Gooch <rgooch@atnf.csiro.au>
476 Changed interface to <devfs_register>.
477 Work sponsored by SGI.
478 v0.101
479 20000622 Richard Gooch <rgooch@atnf.csiro.au>
480 Simplified interface to <devfs_mk_symlink> and <devfs_mk_dir>.
481 Simplified interface to <devfs_find_handle>.
482 Work sponsored by SGI.
483 v0.102
484 20010519 Richard Gooch <rgooch@atnf.csiro.au>
485 Ensure <devfs_generate_path> terminates string for root entry.
486 Exported <devfs_get_name> to modules.
487 20010520 Richard Gooch <rgooch@atnf.csiro.au>
488 Make <devfs_mk_symlink> send events to devfsd.
489 Cleaned up option processing in <devfs_setup>.
490 20010521 Richard Gooch <rgooch@atnf.csiro.au>
491 Fixed bugs in handling symlinks: could leak or cause Oops.
492 20010522 Richard Gooch <rgooch@atnf.csiro.au>
493 Cleaned up directory handling by separating fops.
494 v0.103
495 20010601 Richard Gooch <rgooch@atnf.csiro.au>
496 Fixed handling of inverted options in <devfs_setup>.
497 v0.104
498 20010604 Richard Gooch <rgooch@atnf.csiro.au>
499 Adjusted <try_modload> to account for <devfs_generate_path> fix.
500 v0.105
501 20010617 Richard Gooch <rgooch@atnf.csiro.au>
502 Answered question posed by Al Viro and removed his comments.
503 Moved setting of registered flag after other fields are changed.
504 Fixed race between <devfsd_close> and <devfsd_notify_one>.
505 Global VFS changes added bogus BKL to <devfsd_close>: removed.
506 Widened locking in <devfs_readlink> and <devfs_follow_link>.
507 Replaced <devfsd_read> stack usage with <devfsd_ioctl> kmalloc.
508 Simplified locking in <devfsd_ioctl> and fixed memory leak.
509 v0.106
510 20010709 Richard Gooch <rgooch@atnf.csiro.au>
511 Removed broken devnum allocation and use <devfs_alloc_devnum>.
512 Fixed old devnum leak by calling new <devfs_dealloc_devnum>.
513 v0.107
514 20010712 Richard Gooch <rgooch@atnf.csiro.au>
515 Fixed bug in <devfs_setup> which could hang boot process.
516 v0.108
517 20010730 Richard Gooch <rgooch@atnf.csiro.au>
518 Added DEVFSD_NOTIFY_DELETE event.
519 20010801 Richard Gooch <rgooch@atnf.csiro.au>
520 Removed #include <asm/segment.h>.
521 v0.109
522 20010807 Richard Gooch <rgooch@atnf.csiro.au>
523 Fixed inode table races by removing it and using
524 inode->u.generic_ip instead.
525 Moved <devfs_read_inode> into <get_vfs_inode>.
526 Moved <devfs_write_inode> into <devfs_notify_change>.
527 v0.110
528 20010808 Richard Gooch <rgooch@atnf.csiro.au>
529 Fixed race in <devfs_do_symlink> for uni-processor.
530 v0.111
531 20010818 Richard Gooch <rgooch@atnf.csiro.au>
532 Removed remnant of multi-mount support in <devfs_mknod>.
533 Removed unused DEVFS_FL_SHOW_UNREG flag.
534 v0.112
535 20010820 Richard Gooch <rgooch@atnf.csiro.au>
536 Removed nlink field from struct devfs_inode.
537 v0.113
538 20010823 Richard Gooch <rgooch@atnf.csiro.au>
539 Replaced BKL with global rwsem to protect symlink data (quick
540 and dirty hack).
541 v0.114
542 20010827 Richard Gooch <rgooch@atnf.csiro.au>
543 Replaced global rwsem for symlink with per-link refcount.
544 v0.115
545 20010919 Richard Gooch <rgooch@atnf.csiro.au>
546 Set inode->i_mapping->a_ops for block nodes in <get_vfs_inode>.
547 v0.116
548 20011008 Richard Gooch <rgooch@atnf.csiro.au>
549 Fixed overrun in <devfs_link> by removing function (not needed).
550 20011009 Richard Gooch <rgooch@atnf.csiro.au>
551 Fixed buffer underrun in <try_modload>.
552 20011029 Richard Gooch <rgooch@atnf.csiro.au>
553 Fixed race in <devfsd_ioctl> when setting event mask.
554 20011114 Richard Gooch <rgooch@atnf.csiro.au>
555 First release of new locking code.
556 v1.0
557 20011117 Richard Gooch <rgooch@atnf.csiro.au>
558 Discard temporary buffer, now use "%s" for dentry names.
559 20011118 Richard Gooch <rgooch@atnf.csiro.au>
560 Don't generate path in <try_modload>: use fake entry instead.
561 Use "existing" directory in <_devfs_make_parent_for_leaf>.
562 20011122 Richard Gooch <rgooch@atnf.csiro.au>
563 Use slab cache rather than fixed buffer for devfsd events.
564 v1.1
565 20011125 Richard Gooch <rgooch@atnf.csiro.au>
566 Send DEVFSD_NOTIFY_REGISTERED events in <devfs_mk_dir>.
567 20011127 Richard Gooch <rgooch@atnf.csiro.au>
568 Fixed locking bug in <devfs_d_revalidate_wait> due to typo.
569 Do not send CREATE, CHANGE, ASYNC_OPEN or DELETE events from
570 devfsd or children.
571 v1.2
572 20011202 Richard Gooch <rgooch@atnf.csiro.au>
573 Fixed bug in <devfsd_read>: was dereferencing freed pointer.
574 v1.3
575 20011203 Richard Gooch <rgooch@atnf.csiro.au>
576 Fixed bug in <devfsd_close>: was dereferencing freed pointer.
577 Added process group check for devfsd privileges.
578 v1.4
579 20011204 Richard Gooch <rgooch@atnf.csiro.au>
580 Use SLAB_ATOMIC in <devfsd_notify_de> from <devfs_d_delete>.
581 v1.5
582 20011211 Richard Gooch <rgooch@atnf.csiro.au>
583 Return old entry in <devfs_mk_dir> for 2.4.x kernels.
584 20011212 Richard Gooch <rgooch@atnf.csiro.au>
585 Increment refcount on module in <check_disc_changed>.
586 20011215 Richard Gooch <rgooch@atnf.csiro.au>
587 Created <devfs_get_handle> and exported <devfs_put>.
588 Increment refcount on module in <devfs_get_ops>.
589 Created <devfs_put_ops>.
590 v1.6
591 20011216 Richard Gooch <rgooch@atnf.csiro.au>
592 Added poisoning to <devfs_put>.
593 Improved debugging messages.
594 v1.7
595 20011221 Richard Gooch <rgooch@atnf.csiro.au>
596 Corrected (made useful) debugging message in <unregister>.
597 Moved <kmem_cache_create> in <mount_devfs_fs> to <init_devfs_fs>
598 20011224 Richard Gooch <rgooch@atnf.csiro.au>
599 Added magic number to guard against scribbling drivers.
600 20011226 Richard Gooch <rgooch@atnf.csiro.au>
601 Only return old entry in <devfs_mk_dir> if a directory.
602 Defined macros for error and debug messages.
603 v1.8
604 20020113 Richard Gooch <rgooch@atnf.csiro.au>
605 Fixed (rare, old) race in <devfs_lookup>.
606 v1.9
607 20020120 Richard Gooch <rgooch@atnf.csiro.au>
608 Fixed deadlock bug in <devfs_d_revalidate_wait>.
609 Tag VFS deletable in <devfs_mk_symlink> if handle ignored.
610 v1.10
611 20020129 Richard Gooch <rgooch@atnf.csiro.au>
612 Added KERN_* to remaining messages.
613 Cleaned up declaration of <stat_read>.
614 v1.11
615 20020219 Richard Gooch <rgooch@atnf.csiro.au>
616 Changed <devfs_rmdir> to allow later additions if not yet empty.
617 v1.12
618 20020406 Richard Gooch <rgooch@atnf.csiro.au>
619 Removed silently introduced calls to lock_kernel() and
620 unlock_kernel() due to recent VFS locking changes. BKL isn't
621 required in devfs.
622 v1.13
623 20020428 Richard Gooch <rgooch@atnf.csiro.au>
624 Removed 2.4.x compatibility code.
625 v1.14
626 20020510 Richard Gooch <rgooch@atnf.csiro.au>
627 Added BKL to <devfs_open> because drivers still need it.
628 v1.15
629 20020512 Richard Gooch <rgooch@atnf.csiro.au>
630 Protected <scan_dir_for_removable> and <get_removable_partition>
631 from changing directory contents.
632 v1.16
633 20020514 Richard Gooch <rgooch@atnf.csiro.au>
634 Minor cleanup of <scan_dir_for_removable>.
635 v1.17
636 20020721 Richard Gooch <rgooch@atnf.csiro.au>
637 Switched to ISO C structure field initialisers.
638 Switch to set_current_state() and move before add_wait_queue().
639 20020722 Richard Gooch <rgooch@atnf.csiro.au>
640 Fixed devfs entry leak in <devfs_readdir> when *readdir fails.
641 v1.18
642 20020725 Richard Gooch <rgooch@atnf.csiro.au>
643 Created <devfs_find_and_unregister>.
644 v1.19
645 20020728 Richard Gooch <rgooch@atnf.csiro.au>
646 Removed deprecated <devfs_find_handle>.
647 v1.20
648 20020820 Richard Gooch <rgooch@atnf.csiro.au>
649 Fixed module unload race in <devfs_open>.
650 v1.21
651 20021013 Richard Gooch <rgooch@atnf.csiro.au>
652 Removed DEVFS_ FL_AUTO_OWNER.
653 Switched lingering structure field initialiser to ISO C.
654 Added locking when updating FCB flags.
655 v1.22
656*/
657#include <linux/types.h>
658#include <linux/errno.h>
659#include <linux/time.h>
660#include <linux/tty.h>
661#include <linux/timer.h>
662#include <linux/config.h>
663#include <linux/kernel.h>
664#include <linux/wait.h>
665#include <linux/string.h>
666#include <linux/slab.h>
667#include <linux/ioport.h>
668#include <linux/delay.h>
669#include <linux/ctype.h>
670#include <linux/mm.h>
671#include <linux/module.h>
672#include <linux/init.h>
673#include <linux/devfs_fs.h>
674#include <linux/devfs_fs_kernel.h>
675#include <linux/smp_lock.h>
676#include <linux/smp.h>
677#include <linux/rwsem.h>
678#include <linux/sched.h>
679#include <linux/namei.h>
680#include <linux/bitops.h>
681
682#include <asm/uaccess.h>
683#include <asm/io.h>
684#include <asm/processor.h>
685#include <asm/system.h>
686#include <asm/pgtable.h>
687#include <asm/atomic.h>
688
689#define DEVFS_VERSION "2004-01-31"
690
691#define DEVFS_NAME "devfs"
692
693#define FIRST_INODE 1
694
695#define STRING_LENGTH 256
696#define FAKE_BLOCK_SIZE 1024
697#define POISON_PTR ( *(void **) poison_array )
698#define MAGIC_VALUE 0x327db823
699
700#ifndef TRUE
701# define TRUE 1
702# define FALSE 0
703#endif
704
705#define MODE_DIR (S_IFDIR | S_IWUSR | S_IRUGO | S_IXUGO)
706
707#define DEBUG_NONE 0x0000000
708#define DEBUG_MODULE_LOAD 0x0000001
709#define DEBUG_REGISTER 0x0000002
710#define DEBUG_UNREGISTER 0x0000004
711#define DEBUG_FREE 0x0000008
712#define DEBUG_SET_FLAGS 0x0000010
713#define DEBUG_S_READ 0x0000100 /* Break */
714#define DEBUG_I_LOOKUP 0x0001000 /* Break */
715#define DEBUG_I_CREATE 0x0002000
716#define DEBUG_I_GET 0x0004000
717#define DEBUG_I_CHANGE 0x0008000
718#define DEBUG_I_UNLINK 0x0010000
719#define DEBUG_I_RLINK 0x0020000
720#define DEBUG_I_FLINK 0x0040000
721#define DEBUG_I_MKNOD 0x0080000
722#define DEBUG_F_READDIR 0x0100000 /* Break */
723#define DEBUG_D_DELETE 0x1000000 /* Break */
724#define DEBUG_D_RELEASE 0x2000000
725#define DEBUG_D_IPUT 0x4000000
726#define DEBUG_ALL 0xfffffff
727#define DEBUG_DISABLED DEBUG_NONE
728
729#define OPTION_NONE 0x00
730#define OPTION_MOUNT 0x01
731
732#define PRINTK(format, args...) \
733 {printk (KERN_ERR "%s" format, __FUNCTION__ , ## args);}
734
735#define OOPS(format, args...) \
736 {printk (KERN_CRIT "%s" format, __FUNCTION__ , ## args); \
737 printk ("Forcing Oops\n"); \
738 BUG();}
739
740#ifdef CONFIG_DEVFS_DEBUG
741# define VERIFY_ENTRY(de) \
742 {if ((de) && (de)->magic_number != MAGIC_VALUE) \
743 OOPS ("(%p): bad magic value: %x\n", (de), (de)->magic_number);}
744# define WRITE_ENTRY_MAGIC(de,magic) (de)->magic_number = (magic)
745# define DPRINTK(flag, format, args...) \
746 {if (devfs_debug & flag) \
747 printk (KERN_INFO "%s" format, __FUNCTION__ , ## args);}
748#else
749# define VERIFY_ENTRY(de)
750# define WRITE_ENTRY_MAGIC(de,magic)
751# define DPRINTK(flag, format, args...)
752#endif
753
754typedef struct devfs_entry *devfs_handle_t;
755
756struct directory_type {
757 rwlock_t lock; /* Lock for searching(R)/updating(W) */
758 struct devfs_entry *first;
759 struct devfs_entry *last;
760 unsigned char no_more_additions:1;
761};
762
763struct symlink_type {
764 unsigned int length; /* Not including the NULL-termimator */
765 char *linkname; /* This is NULL-terminated */
766};
767
768struct devfs_inode { /* This structure is for "persistent" inode storage */
769 struct dentry *dentry;
770 struct timespec atime;
771 struct timespec mtime;
772 struct timespec ctime;
773 unsigned int ino; /* Inode number as seen in the VFS */
774 uid_t uid;
775 gid_t gid;
776};
777
778struct devfs_entry {
779#ifdef CONFIG_DEVFS_DEBUG
780 unsigned int magic_number;
781#endif
782 void *info;
783 atomic_t refcount; /* When this drops to zero, it's unused */
784 union {
785 struct directory_type dir;
786 dev_t dev;
787 struct symlink_type symlink;
788 const char *name; /* Only used for (mode == 0) */
789 } u;
790 struct devfs_entry *prev; /* Previous entry in the parent directory */
791 struct devfs_entry *next; /* Next entry in the parent directory */
792 struct devfs_entry *parent; /* The parent directory */
793 struct devfs_inode inode;
794 umode_t mode;
795 unsigned short namelen; /* I think 64k+ filenames are a way off... */
796 unsigned char vfs:1; /* Whether the VFS may delete the entry */
797 char name[1]; /* This is just a dummy: the allocated array
798 is bigger. This is NULL-terminated */
799};
800
801/* The root of the device tree */
802static struct devfs_entry *root_entry;
803
804struct devfsd_buf_entry {
805 struct devfs_entry *de; /* The name is generated with this */
806 unsigned short type; /* The type of event */
807 umode_t mode;
808 uid_t uid;
809 gid_t gid;
810 struct devfsd_buf_entry *next;
811};
812
813struct fs_info { /* This structure is for the mounted devfs */
814 struct super_block *sb;
815 spinlock_t devfsd_buffer_lock; /* Lock when inserting/deleting events */
816 struct devfsd_buf_entry *devfsd_first_event;
817 struct devfsd_buf_entry *devfsd_last_event;
818 volatile int devfsd_sleeping;
819 volatile struct task_struct *devfsd_task;
820 volatile pid_t devfsd_pgrp;
821 volatile struct file *devfsd_file;
822 struct devfsd_notify_struct *devfsd_info;
823 volatile unsigned long devfsd_event_mask;
824 atomic_t devfsd_overrun_count;
825 wait_queue_head_t devfsd_wait_queue; /* Wake devfsd on input */
826 wait_queue_head_t revalidate_wait_queue; /* Wake when devfsd sleeps */
827};
828
829static struct fs_info fs_info = {.devfsd_buffer_lock = SPIN_LOCK_UNLOCKED };
830static kmem_cache_t *devfsd_buf_cache;
831#ifdef CONFIG_DEVFS_DEBUG
832static unsigned int devfs_debug_init __initdata = DEBUG_NONE;
833static unsigned int devfs_debug = DEBUG_NONE;
834static DEFINE_SPINLOCK(stat_lock);
835static unsigned int stat_num_entries;
836static unsigned int stat_num_bytes;
837#endif
838static unsigned char poison_array[8] =
839 { 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a };
840
841#ifdef CONFIG_DEVFS_MOUNT
842static unsigned int boot_options = OPTION_MOUNT;
843#else
844static unsigned int boot_options = OPTION_NONE;
845#endif
846
847/* Forward function declarations */
848static devfs_handle_t _devfs_walk_path(struct devfs_entry *dir,
849 const char *name, int namelen,
850 int traverse_symlink);
851static ssize_t devfsd_read(struct file *file, char __user *buf, size_t len,
852 loff_t * ppos);
853static int devfsd_ioctl(struct inode *inode, struct file *file,
854 unsigned int cmd, unsigned long arg);
855static int devfsd_close(struct inode *inode, struct file *file);
856#ifdef CONFIG_DEVFS_DEBUG
857static ssize_t stat_read(struct file *file, char __user *buf, size_t len,
858 loff_t * ppos);
859static const struct file_operations stat_fops = {
860 .open = nonseekable_open,
861 .read = stat_read,
862};
863#endif
864
865/* Devfs daemon file operations */
866static const struct file_operations devfsd_fops = {
867 .open = nonseekable_open,
868 .read = devfsd_read,
869 .ioctl = devfsd_ioctl,
870 .release = devfsd_close,
871};
872
873/* Support functions follow */
874
875/**
876 * devfs_get - Get a reference to a devfs entry.
877 * @de: The devfs entry.
878 */
879
880static struct devfs_entry *devfs_get(struct devfs_entry *de)
881{
882 VERIFY_ENTRY(de);
883 if (de)
884 atomic_inc(&de->refcount);
885 return de;
886} /* End Function devfs_get */
887
888/**
889 * devfs_put - Put (release) a reference to a devfs entry.
890 * @de: The handle to the devfs entry.
891 */
892
893static void devfs_put(devfs_handle_t de)
894{
895 if (!de)
896 return;
897 VERIFY_ENTRY(de);
898 if (de->info == POISON_PTR)
899 OOPS("(%p): poisoned pointer\n", de);
900 if (!atomic_dec_and_test(&de->refcount))
901 return;
902 if (de == root_entry)
903 OOPS("(%p): root entry being freed\n", de);
904 DPRINTK(DEBUG_FREE, "(%s): de: %p, parent: %p \"%s\"\n",
905 de->name, de, de->parent,
906 de->parent ? de->parent->name : "no parent");
907 if (S_ISLNK(de->mode))
908 kfree(de->u.symlink.linkname);
909 WRITE_ENTRY_MAGIC(de, 0);
910#ifdef CONFIG_DEVFS_DEBUG
911 spin_lock(&stat_lock);
912 --stat_num_entries;
913 stat_num_bytes -= sizeof *de + de->namelen;
914 if (S_ISLNK(de->mode))
915 stat_num_bytes -= de->u.symlink.length + 1;
916 spin_unlock(&stat_lock);
917#endif
918 de->info = POISON_PTR;
919 kfree(de);
920} /* End Function devfs_put */
921
922/**
923 * _devfs_search_dir - Search for a devfs entry in a directory.
924 * @dir: The directory to search.
925 * @name: The name of the entry to search for.
926 * @namelen: The number of characters in @name.
927 *
928 * Search for a devfs entry in a directory and returns a pointer to the entry
929 * on success, else %NULL. The directory must be locked already.
930 * An implicit devfs_get() is performed on the returned entry.
931 */
932
933static struct devfs_entry *_devfs_search_dir(struct devfs_entry *dir,
934 const char *name,
935 unsigned int namelen)
936{
937 struct devfs_entry *curr;
938
939 if (!S_ISDIR(dir->mode)) {
940 PRINTK("(%s): not a directory\n", dir->name);
941 return NULL;
942 }
943 for (curr = dir->u.dir.first; curr != NULL; curr = curr->next) {
944 if (curr->namelen != namelen)
945 continue;
946 if (memcmp(curr->name, name, namelen) == 0)
947 break;
948 /* Not found: try the next one */
949 }
950 return devfs_get(curr);
951} /* End Function _devfs_search_dir */
952
953/**
954 * _devfs_alloc_entry - Allocate a devfs entry.
955 * @name: the name of the entry
956 * @namelen: the number of characters in @name
957 * @mode: the mode for the entry
958 *
959 * Allocate a devfs entry and returns a pointer to the entry on success, else
960 * %NULL.
961 */
962
963static struct devfs_entry *_devfs_alloc_entry(const char *name,
964 unsigned int namelen,
965 umode_t mode)
966{
967 struct devfs_entry *new;
968 static unsigned long inode_counter = FIRST_INODE;
969 static DEFINE_SPINLOCK(counter_lock);
970
971 if (name && (namelen < 1))
972 namelen = strlen(name);
973 if ((new = kmalloc(sizeof *new + namelen, GFP_KERNEL)) == NULL)
974 return NULL;
975 memset(new, 0, sizeof *new + namelen); /* Will set '\0' on name */
976 new->mode = mode;
977 if (S_ISDIR(mode))
978 rwlock_init(&new->u.dir.lock);
979 atomic_set(&new->refcount, 1);
980 spin_lock(&counter_lock);
981 new->inode.ino = inode_counter++;
982 spin_unlock(&counter_lock);
983 if (name)
984 memcpy(new->name, name, namelen);
985 new->namelen = namelen;
986 WRITE_ENTRY_MAGIC(new, MAGIC_VALUE);
987#ifdef CONFIG_DEVFS_DEBUG
988 spin_lock(&stat_lock);
989 ++stat_num_entries;
990 stat_num_bytes += sizeof *new + namelen;
991 spin_unlock(&stat_lock);
992#endif
993 return new;
994} /* End Function _devfs_alloc_entry */
995
996/**
997 * _devfs_append_entry - Append a devfs entry to a directory's child list.
998 * @dir: The directory to add to.
999 * @de: The devfs entry to append.
1000 * @old_de: If an existing entry exists, it will be written here. This may
1001 * be %NULL. An implicit devfs_get() is performed on this entry.
1002 *
1003 * Append a devfs entry to a directory's list of children, checking first to
1004 * see if an entry of the same name exists. The directory will be locked.
1005 * The value 0 is returned on success, else a negative error code.
1006 * On failure, an implicit devfs_put() is performed on %de.
1007 */
1008
1009static int _devfs_append_entry(devfs_handle_t dir, devfs_handle_t de,
1010 devfs_handle_t * old_de)
1011{
1012 int retval;
1013
1014 if (old_de)
1015 *old_de = NULL;
1016 if (!S_ISDIR(dir->mode)) {
1017 PRINTK("(%s): dir: \"%s\" is not a directory\n", de->name,
1018 dir->name);
1019 devfs_put(de);
1020 return -ENOTDIR;
1021 }
1022 write_lock(&dir->u.dir.lock);
1023 if (dir->u.dir.no_more_additions)
1024 retval = -ENOENT;
1025 else {
1026 struct devfs_entry *old;
1027
1028 old = _devfs_search_dir(dir, de->name, de->namelen);
1029 if (old_de)
1030 *old_de = old;
1031 else
1032 devfs_put(old);
1033 if (old == NULL) {
1034 de->parent = dir;
1035 de->prev = dir->u.dir.last;
1036 /* Append to the directory's list of children */
1037 if (dir->u.dir.first == NULL)
1038 dir->u.dir.first = de;
1039 else
1040 dir->u.dir.last->next = de;
1041 dir->u.dir.last = de;
1042 retval = 0;
1043 } else
1044 retval = -EEXIST;
1045 }
1046 write_unlock(&dir->u.dir.lock);
1047 if (retval)
1048 devfs_put(de);
1049 return retval;
1050} /* End Function _devfs_append_entry */
1051
1052/**
1053 * _devfs_get_root_entry - Get the root devfs entry.
1054 *
1055 * Returns the root devfs entry on success, else %NULL.
1056 *
1057 * TODO it must be called asynchronously due to the fact
1058 * that devfs is initialized relatively late. Proper way
1059 * is to remove module_init from init_devfs_fs and manually
1060 * call it early enough during system init
1061 */
1062
1063static struct devfs_entry *_devfs_get_root_entry(void)
1064{
1065 struct devfs_entry *new;
1066 static DEFINE_SPINLOCK(root_lock);
1067
1068 if (root_entry)
1069 return root_entry;
1070
1071 new = _devfs_alloc_entry(NULL, 0, MODE_DIR);
1072 if (new == NULL)
1073 return NULL;
1074
1075 spin_lock(&root_lock);
1076 if (root_entry) {
1077 spin_unlock(&root_lock);
1078 devfs_put(new);
1079 return root_entry;
1080 }
1081 root_entry = new;
1082 spin_unlock(&root_lock);
1083
1084 return root_entry;
1085} /* End Function _devfs_get_root_entry */
1086
1087/**
1088 * _devfs_descend - Descend down a tree using the next component name.
1089 * @dir: The directory to search.
1090 * @name: The component name to search for.
1091 * @namelen: The length of %name.
1092 * @next_pos: The position of the next '/' or '\0' is written here.
1093 *
1094 * Descend into a directory, searching for a component. This function forms
1095 * the core of a tree-walking algorithm. The directory will be locked.
1096 * The devfs entry corresponding to the component is returned. If there is
1097 * no matching entry, %NULL is returned.
1098 * An implicit devfs_get() is performed on the returned entry.
1099 */
1100
1101static struct devfs_entry *_devfs_descend(struct devfs_entry *dir,
1102 const char *name, int namelen,
1103 int *next_pos)
1104{
1105 const char *stop, *ptr;
1106 struct devfs_entry *entry;
1107
1108 if ((namelen >= 3) && (strncmp(name, "../", 3) == 0)) { /* Special-case going to parent directory */
1109 *next_pos = 3;
1110 return devfs_get(dir->parent);
1111 }
1112 stop = name + namelen;
1113 /* Search for a possible '/' */
1114 for (ptr = name; (ptr < stop) && (*ptr != '/'); ++ptr) ;
1115 *next_pos = ptr - name;
1116 read_lock(&dir->u.dir.lock);
1117 entry = _devfs_search_dir(dir, name, *next_pos);
1118 read_unlock(&dir->u.dir.lock);
1119 return entry;
1120} /* End Function _devfs_descend */
1121
1122static devfs_handle_t _devfs_make_parent_for_leaf(struct devfs_entry *dir,
1123 const char *name,
1124 int namelen, int *leaf_pos)
1125{
1126 int next_pos = 0;
1127
1128 if (dir == NULL)
1129 dir = _devfs_get_root_entry();
1130 if (dir == NULL)
1131 return NULL;
1132 devfs_get(dir);
1133 /* Search for possible trailing component and ignore it */
1134 for (--namelen; (namelen > 0) && (name[namelen] != '/'); --namelen) ;
1135 *leaf_pos = (name[namelen] == '/') ? (namelen + 1) : 0;
1136 for (; namelen > 0; name += next_pos, namelen -= next_pos) {
1137 struct devfs_entry *de, *old = NULL;
1138
1139 if ((de =
1140 _devfs_descend(dir, name, namelen, &next_pos)) == NULL) {
1141 de = _devfs_alloc_entry(name, next_pos, MODE_DIR);
1142 devfs_get(de);
1143 if (!de || _devfs_append_entry(dir, de, &old)) {
1144 devfs_put(de);
1145 if (!old || !S_ISDIR(old->mode)) {
1146 devfs_put(old);
1147 devfs_put(dir);
1148 return NULL;
1149 }
1150 de = old; /* Use the existing directory */
1151 }
1152 }
1153 if (de == dir->parent) {
1154 devfs_put(dir);
1155 devfs_put(de);
1156 return NULL;
1157 }
1158 devfs_put(dir);
1159 dir = de;
1160 if (name[next_pos] == '/')
1161 ++next_pos;
1162 }
1163 return dir;
1164} /* End Function _devfs_make_parent_for_leaf */
1165
1166static devfs_handle_t _devfs_prepare_leaf(devfs_handle_t * dir,
1167 const char *name, umode_t mode)
1168{
1169 int namelen, leaf_pos;
1170 struct devfs_entry *de;
1171
1172 namelen = strlen(name);
1173 if ((*dir = _devfs_make_parent_for_leaf(*dir, name, namelen,
1174 &leaf_pos)) == NULL) {
1175 PRINTK("(%s): could not create parent path\n", name);
1176 return NULL;
1177 }
1178 if ((de = _devfs_alloc_entry(name + leaf_pos, namelen - leaf_pos, mode))
1179 == NULL) {
1180 PRINTK("(%s): could not allocate entry\n", name);
1181 devfs_put(*dir);
1182 return NULL;
1183 }
1184 return de;
1185} /* End Function _devfs_prepare_leaf */
1186
1187static devfs_handle_t _devfs_walk_path(struct devfs_entry *dir,
1188 const char *name, int namelen,
1189 int traverse_symlink)
1190{
1191 int next_pos = 0;
1192
1193 if (dir == NULL)
1194 dir = _devfs_get_root_entry();
1195 if (dir == NULL)
1196 return NULL;
1197 devfs_get(dir);
1198 for (; namelen > 0; name += next_pos, namelen -= next_pos) {
1199 struct devfs_entry *de, *link;
1200
1201 if (!S_ISDIR(dir->mode)) {
1202 devfs_put(dir);
1203 return NULL;
1204 }
1205
1206 if ((de =
1207 _devfs_descend(dir, name, namelen, &next_pos)) == NULL) {
1208 devfs_put(dir);
1209 return NULL;
1210 }
1211 if (S_ISLNK(de->mode) && traverse_symlink) { /* Need to follow the link: this is a stack chomper */
1212 /* FIXME what if it puts outside of mounted tree? */
1213 link = _devfs_walk_path(dir, de->u.symlink.linkname,
1214 de->u.symlink.length, TRUE);
1215 devfs_put(de);
1216 if (!link) {
1217 devfs_put(dir);
1218 return NULL;
1219 }
1220 de = link;
1221 }
1222 devfs_put(dir);
1223 dir = de;
1224 if (name[next_pos] == '/')
1225 ++next_pos;
1226 }
1227 return dir;
1228} /* End Function _devfs_walk_path */
1229
1230/**
1231 * _devfs_find_entry - Find a devfs entry.
1232 * @dir: The handle to the parent devfs directory entry. If this is %NULL the
1233 * name is relative to the root of the devfs.
1234 * @name: The name of the entry. This may be %NULL.
1235 * @traverse_symlink: If %TRUE then symbolic links are traversed.
1236 *
1237 * Returns the devfs_entry pointer on success, else %NULL. An implicit
1238 * devfs_get() is performed.
1239 */
1240
1241static struct devfs_entry *_devfs_find_entry(devfs_handle_t dir,
1242 const char *name,
1243 int traverse_symlink)
1244{
1245 unsigned int namelen = strlen(name);
1246
1247 if (name[0] == '/') {
1248 /* Skip leading pathname component */
1249 if (namelen < 2) {
1250 PRINTK("(%s): too short\n", name);
1251 return NULL;
1252 }
1253 for (++name, --namelen; (*name != '/') && (namelen > 0);
1254 ++name, --namelen) ;
1255 if (namelen < 2) {
1256 PRINTK("(%s): too short\n", name);
1257 return NULL;
1258 }
1259 ++name;
1260 --namelen;
1261 }
1262 return _devfs_walk_path(dir, name, namelen, traverse_symlink);
1263} /* End Function _devfs_find_entry */
1264
1265static struct devfs_entry *get_devfs_entry_from_vfs_inode(struct inode *inode)
1266{
1267 if (inode == NULL)
1268 return NULL;
1269 VERIFY_ENTRY((struct devfs_entry *)inode->u.generic_ip);
1270 return inode->u.generic_ip;
1271} /* End Function get_devfs_entry_from_vfs_inode */
1272
1273/**
1274 * free_dentry - Free the dentry for a device entry and invalidate inode.
1275 * @de: The entry.
1276 *
1277 * This must only be called after the entry has been unhooked from its
1278 * parent directory.
1279 */
1280
1281static void free_dentry(struct devfs_entry *de)
1282{
1283 struct dentry *dentry = de->inode.dentry;
1284
1285 if (!dentry)
1286 return;
1287 spin_lock(&dcache_lock);
1288 dget_locked(dentry);
1289 spin_unlock(&dcache_lock);
1290 /* Forcefully remove the inode */
1291 if (dentry->d_inode != NULL)
1292 dentry->d_inode->i_nlink = 0;
1293 d_drop(dentry);
1294 dput(dentry);
1295} /* End Function free_dentry */
1296
1297/**
1298 * is_devfsd_or_child - Test if the current process is devfsd or one of its children.
1299 * @fs_info: The filesystem information.
1300 *
1301 * Returns %TRUE if devfsd or child, else %FALSE.
1302 */
1303
1304static int is_devfsd_or_child(struct fs_info *fs_info)
1305{
1306 struct task_struct *p = current;
1307
1308 if (p == fs_info->devfsd_task)
1309 return (TRUE);
1310 if (process_group(p) == fs_info->devfsd_pgrp)
1311 return (TRUE);
1312 read_lock(&tasklist_lock);
1313 for (; p != &init_task; p = p->real_parent) {
1314 if (p == fs_info->devfsd_task) {
1315 read_unlock(&tasklist_lock);
1316 return (TRUE);
1317 }
1318 }
1319 read_unlock(&tasklist_lock);
1320 return (FALSE);
1321} /* End Function is_devfsd_or_child */
1322
1323/**
1324 * devfsd_queue_empty - Test if devfsd has work pending in its event queue.
1325 * @fs_info: The filesystem information.
1326 *
1327 * Returns %TRUE if the queue is empty, else %FALSE.
1328 */
1329
1330static inline int devfsd_queue_empty(struct fs_info *fs_info)
1331{
1332 return (fs_info->devfsd_last_event) ? FALSE : TRUE;
1333} /* End Function devfsd_queue_empty */
1334
1335/**
1336 * wait_for_devfsd_finished - Wait for devfsd to finish processing its event queue.
1337 * @fs_info: The filesystem information.
1338 *
1339 * Returns %TRUE if no more waiting will be required, else %FALSE.
1340 */
1341
1342static int wait_for_devfsd_finished(struct fs_info *fs_info)
1343{
1344 DECLARE_WAITQUEUE(wait, current);
1345
1346 if (fs_info->devfsd_task == NULL)
1347 return (TRUE);
1348 if (devfsd_queue_empty(fs_info) && fs_info->devfsd_sleeping)
1349 return TRUE;
1350 if (is_devfsd_or_child(fs_info))
1351 return (FALSE);
1352 set_current_state(TASK_UNINTERRUPTIBLE);
1353 add_wait_queue(&fs_info->revalidate_wait_queue, &wait);
1354 if (!devfsd_queue_empty(fs_info) || !fs_info->devfsd_sleeping)
1355 if (fs_info->devfsd_task)
1356 schedule();
1357 remove_wait_queue(&fs_info->revalidate_wait_queue, &wait);
1358 __set_current_state(TASK_RUNNING);
1359 return (TRUE);
1360} /* End Function wait_for_devfsd_finished */
1361
1362/**
1363 * devfsd_notify_de - Notify the devfsd daemon of a change.
1364 * @de: The devfs entry that has changed. This and all parent entries will
1365 * have their reference counts incremented if the event was queued.
1366 * @type: The type of change.
1367 * @mode: The mode of the entry.
1368 * @uid: The user ID.
1369 * @gid: The group ID.
1370 * @fs_info: The filesystem info.
1371 *
1372 * Returns %TRUE if an event was queued and devfsd woken up, else %FALSE.
1373 */
1374
1375static int devfsd_notify_de(struct devfs_entry *de,
1376 unsigned short type, umode_t mode,
1377 uid_t uid, gid_t gid, struct fs_info *fs_info)
1378{
1379 struct devfsd_buf_entry *entry;
1380 struct devfs_entry *curr;
1381
1382 if (!(fs_info->devfsd_event_mask & (1 << type)))
1383 return (FALSE);
1384 if ((entry = kmem_cache_alloc(devfsd_buf_cache, SLAB_KERNEL)) == NULL) {
1385 atomic_inc(&fs_info->devfsd_overrun_count);
1386 return (FALSE);
1387 }
1388 for (curr = de; curr != NULL; curr = curr->parent)
1389 devfs_get(curr);
1390 entry->de = de;
1391 entry->type = type;
1392 entry->mode = mode;
1393 entry->uid = uid;
1394 entry->gid = gid;
1395 entry->next = NULL;
1396 spin_lock(&fs_info->devfsd_buffer_lock);
1397 if (!fs_info->devfsd_first_event)
1398 fs_info->devfsd_first_event = entry;
1399 if (fs_info->devfsd_last_event)
1400 fs_info->devfsd_last_event->next = entry;
1401 fs_info->devfsd_last_event = entry;
1402 spin_unlock(&fs_info->devfsd_buffer_lock);
1403 wake_up_interruptible(&fs_info->devfsd_wait_queue);
1404 return (TRUE);
1405} /* End Function devfsd_notify_de */
1406
1407/**
1408 * devfsd_notify - Notify the devfsd daemon of a change.
1409 * @de: The devfs entry that has changed.
1410 * @type: The type of change event.
1411 * @wait: If TRUE, the function waits for the daemon to finish processing
1412 * the event.
1413 */
1414
1415static void devfsd_notify(struct devfs_entry *de, unsigned short type)
1416{
1417 devfsd_notify_de(de, type, de->mode, current->euid,
1418 current->egid, &fs_info);
1419}
1420
1421static int devfs_mk_dev(dev_t dev, umode_t mode, const char *fmt, va_list args)
1422{
1423 struct devfs_entry *dir = NULL, *de;
1424 char buf[64];
1425 int error, n;
1426
1427 n = vsnprintf(buf, sizeof(buf), fmt, args);
1428 if (n >= sizeof(buf) || !buf[0]) {
1429 printk(KERN_WARNING "%s: invalid format string %s\n",
1430 __FUNCTION__, fmt);
1431 return -EINVAL;
1432 }
1433
1434 de = _devfs_prepare_leaf(&dir, buf, mode);
1435 if (!de) {
1436 printk(KERN_WARNING "%s: could not prepare leaf for %s\n",
1437 __FUNCTION__, buf);
1438 return -ENOMEM; /* could be more accurate... */
1439 }
1440
1441 de->u.dev = dev;
1442
1443 error = _devfs_append_entry(dir, de, NULL);
1444 if (error) {
1445 printk(KERN_WARNING "%s: could not append to parent for %s\n",
1446 __FUNCTION__, buf);
1447 goto out;
1448 }
1449
1450 devfsd_notify(de, DEVFSD_NOTIFY_REGISTERED);
1451 out:
1452 devfs_put(dir);
1453 return error;
1454}
1455
1456int devfs_mk_bdev(dev_t dev, umode_t mode, const char *fmt, ...)
1457{
1458 va_list args;
1459
1460 if (!S_ISBLK(mode)) {
1461 printk(KERN_WARNING "%s: invalide mode (%u) for %s\n",
1462 __FUNCTION__, mode, fmt);
1463 return -EINVAL;
1464 }
1465
1466 va_start(args, fmt);
1467 return devfs_mk_dev(dev, mode, fmt, args);
1468}
1469
1470EXPORT_SYMBOL(devfs_mk_bdev);
1471
1472int devfs_mk_cdev(dev_t dev, umode_t mode, const char *fmt, ...)
1473{
1474 va_list args;
1475
1476 if (!S_ISCHR(mode)) {
1477 printk(KERN_WARNING "%s: invalide mode (%u) for %s\n",
1478 __FUNCTION__, mode, fmt);
1479 return -EINVAL;
1480 }
1481
1482 va_start(args, fmt);
1483 return devfs_mk_dev(dev, mode, fmt, args);
1484}
1485
1486EXPORT_SYMBOL(devfs_mk_cdev);
1487
1488/**
1489 * _devfs_unhook - Unhook a device entry from its parents list
1490 * @de: The entry to unhook.
1491 *
1492 * Returns %TRUE if the entry was unhooked, else %FALSE if it was
1493 * previously unhooked.
1494 * The caller must have a write lock on the parent directory.
1495 */
1496
1497static int _devfs_unhook(struct devfs_entry *de)
1498{
1499 struct devfs_entry *parent;
1500
1501 if (!de || (de->prev == de))
1502 return FALSE;
1503 parent = de->parent;
1504 if (de->prev == NULL)
1505 parent->u.dir.first = de->next;
1506 else
1507 de->prev->next = de->next;
1508 if (de->next == NULL)
1509 parent->u.dir.last = de->prev;
1510 else
1511 de->next->prev = de->prev;
1512 de->prev = de; /* Indicate we're unhooked */
1513 de->next = NULL; /* Force early termination for <devfs_readdir> */
1514 return TRUE;
1515} /* End Function _devfs_unhook */
1516
1517/**
1518 * _devfs_unregister - Unregister a device entry from its parent.
1519 * @dir: The parent directory.
1520 * @de: The entry to unregister.
1521 *
1522 * The caller must have a write lock on the parent directory, which is
1523 * unlocked by this function.
1524 */
1525
1526static void _devfs_unregister(struct devfs_entry *dir, struct devfs_entry *de)
1527{
1528 int unhooked = _devfs_unhook(de);
1529
1530 write_unlock(&dir->u.dir.lock);
1531 if (!unhooked)
1532 return;
1533 devfs_get(dir);
1534 devfsd_notify(de, DEVFSD_NOTIFY_UNREGISTERED);
1535 free_dentry(de);
1536 devfs_put(dir);
1537 if (!S_ISDIR(de->mode))
1538 return;
1539 while (TRUE) { /* Recursively unregister: this is a stack chomper */
1540 struct devfs_entry *child;
1541
1542 write_lock(&de->u.dir.lock);
1543 de->u.dir.no_more_additions = TRUE;
1544 child = de->u.dir.first;
1545 VERIFY_ENTRY(child);
1546 _devfs_unregister(de, child);
1547 if (!child)
1548 break;
1549 DPRINTK(DEBUG_UNREGISTER, "(%s): child: %p refcount: %d\n",
1550 child->name, child, atomic_read(&child->refcount));
1551 devfs_put(child);
1552 }
1553} /* End Function _devfs_unregister */
1554
1555static int devfs_do_symlink(devfs_handle_t dir, const char *name,
1556 const char *link, devfs_handle_t * handle)
1557{
1558 int err;
1559 unsigned int linklength;
1560 char *newlink;
1561 struct devfs_entry *de;
1562
1563 if (handle != NULL)
1564 *handle = NULL;
1565 if (name == NULL) {
1566 PRINTK("(): NULL name pointer\n");
1567 return -EINVAL;
1568 }
1569 if (link == NULL) {
1570 PRINTK("(%s): NULL link pointer\n", name);
1571 return -EINVAL;
1572 }
1573 linklength = strlen(link);
1574 if ((newlink = kmalloc(linklength + 1, GFP_KERNEL)) == NULL)
1575 return -ENOMEM;
1576 memcpy(newlink, link, linklength);
1577 newlink[linklength] = '\0';
1578 if ((de = _devfs_prepare_leaf(&dir, name, S_IFLNK | S_IRUGO | S_IXUGO))
1579 == NULL) {
1580 PRINTK("(%s): could not prepare leaf\n", name);
1581 kfree(newlink);
1582 return -ENOTDIR;
1583 }
1584 de->info = NULL;
1585 de->u.symlink.linkname = newlink;
1586 de->u.symlink.length = linklength;
1587 if ((err = _devfs_append_entry(dir, de, NULL)) != 0) {
1588 PRINTK("(%s): could not append to parent, err: %d\n", name,
1589 err);
1590 devfs_put(dir);
1591 return err;
1592 }
1593 devfs_put(dir);
1594#ifdef CONFIG_DEVFS_DEBUG
1595 spin_lock(&stat_lock);
1596 stat_num_bytes += linklength + 1;
1597 spin_unlock(&stat_lock);
1598#endif
1599 if (handle != NULL)
1600 *handle = de;
1601 return 0;
1602} /* End Function devfs_do_symlink */
1603
1604/**
1605 * devfs_mk_symlink Create a symbolic link in the devfs namespace.
1606 * @from: The name of the entry.
1607 * @to: Name of the destination
1608 *
1609 * Returns 0 on success, else a negative error code is returned.
1610 */
1611
1612int devfs_mk_symlink(const char *from, const char *to)
1613{
1614 devfs_handle_t de;
1615 int err;
1616
1617 err = devfs_do_symlink(NULL, from, to, &de);
1618 if (!err) {
1619 de->vfs = TRUE;
1620 devfsd_notify(de, DEVFSD_NOTIFY_REGISTERED);
1621 }
1622
1623 return err;
1624}
1625
1626/**
1627 * devfs_mk_dir - Create a directory in the devfs namespace.
1628 * new name is relative to the root of the devfs.
1629 * @fmt: The name of the entry.
1630 *
1631 * Use of this function is optional. The devfs_register() function
1632 * will automatically create intermediate directories as needed. This function
1633 * is provided for efficiency reasons, as it provides a handle to a directory.
1634 * On failure %NULL is returned.
1635 */
1636
1637int devfs_mk_dir(const char *fmt, ...)
1638{
1639 struct devfs_entry *dir = NULL, *de = NULL, *old;
1640 char buf[64];
1641 va_list args;
1642 int error, n;
1643
1644 va_start(args, fmt);
1645 n = vsnprintf(buf, 64, fmt, args);
1646 if (n >= 64 || !buf[0]) {
1647 printk(KERN_WARNING "%s: invalid argument.", __FUNCTION__);
1648 return -EINVAL;
1649 }
1650
1651 de = _devfs_prepare_leaf(&dir, buf, MODE_DIR);
1652 if (!de) {
1653 PRINTK("(%s): could not prepare leaf\n", buf);
1654 return -EINVAL;
1655 }
1656
1657 error = _devfs_append_entry(dir, de, &old);
1658 if (error == -EEXIST && S_ISDIR(old->mode)) {
1659 /*
1660 * devfs_mk_dir() of an already-existing directory will
1661 * return success.
1662 */
1663 error = 0;
1664 goto out_put;
1665 } else if (error) {
1666 PRINTK("(%s): could not append to dir: %p \"%s\"\n",
1667 buf, dir, dir->name);
1668 devfs_put(old);
1669 goto out_put;
1670 }
1671
1672 devfsd_notify(de, DEVFSD_NOTIFY_REGISTERED);
1673
1674 out_put:
1675 devfs_put(dir);
1676 return error;
1677}
1678
1679void devfs_remove(const char *fmt, ...)
1680{
1681 char buf[64];
1682 va_list args;
1683 int n;
1684
1685 va_start(args, fmt);
1686 n = vsnprintf(buf, sizeof(buf), fmt, args);
1687 if (n < sizeof(buf) && buf[0]) {
1688 devfs_handle_t de = _devfs_find_entry(NULL, buf, 0);
1689
1690 if (!de) {
1691 printk(KERN_ERR "%s: %s not found, cannot remove\n",
1692 __FUNCTION__, buf);
1693 dump_stack();
1694 return;
1695 }
1696
1697 write_lock(&de->parent->u.dir.lock);
1698 _devfs_unregister(de->parent, de);
1699 devfs_put(de);
1700 devfs_put(de);
1701 }
1702}
1703
1704/**
1705 * devfs_generate_path - Generate a pathname for an entry, relative to the devfs root.
1706 * @de: The devfs entry.
1707 * @path: The buffer to write the pathname to. The pathname and '\0'
1708 * terminator will be written at the end of the buffer.
1709 * @buflen: The length of the buffer.
1710 *
1711 * Returns the offset in the buffer where the pathname starts on success,
1712 * else a negative error code.
1713 */
1714
1715static int devfs_generate_path(devfs_handle_t de, char *path, int buflen)
1716{
1717 int pos;
1718#define NAMEOF(de) ( (de)->mode ? (de)->name : (de)->u.name )
1719
1720 if (de == NULL)
1721 return -EINVAL;
1722 VERIFY_ENTRY(de);
1723 if (de->namelen >= buflen)
1724 return -ENAMETOOLONG; /* Must be first */
1725 path[buflen - 1] = '\0';
1726 if (de->parent == NULL)
1727 return buflen - 1; /* Don't prepend root */
1728 pos = buflen - de->namelen - 1;
1729 memcpy(path + pos, NAMEOF(de), de->namelen);
1730 for (de = de->parent; de->parent != NULL; de = de->parent) {
1731 if (pos - de->namelen - 1 < 0)
1732 return -ENAMETOOLONG;
1733 path[--pos] = '/';
1734 pos -= de->namelen;
1735 memcpy(path + pos, NAMEOF(de), de->namelen);
1736 }
1737 return pos;
1738} /* End Function devfs_generate_path */
1739
1740/**
1741 * devfs_setup - Process kernel boot options.
1742 * @str: The boot options after the "devfs=".
1743 */
1744
1745static int __init devfs_setup(char *str)
1746{
1747 static struct {
1748 char *name;
1749 unsigned int mask;
1750 unsigned int *opt;
1751 } devfs_options_tab[] __initdata = {
1752#ifdef CONFIG_DEVFS_DEBUG
1753 {
1754 "dall", DEBUG_ALL, &devfs_debug_init}, {
1755 "dmod", DEBUG_MODULE_LOAD, &devfs_debug_init}, {
1756 "dreg", DEBUG_REGISTER, &devfs_debug_init}, {
1757 "dunreg", DEBUG_UNREGISTER, &devfs_debug_init}, {
1758 "dfree", DEBUG_FREE, &devfs_debug_init}, {
1759 "diget", DEBUG_I_GET, &devfs_debug_init}, {
1760 "dchange", DEBUG_SET_FLAGS, &devfs_debug_init}, {
1761 "dsread", DEBUG_S_READ, &devfs_debug_init}, {
1762 "dichange", DEBUG_I_CHANGE, &devfs_debug_init}, {
1763 "dimknod", DEBUG_I_MKNOD, &devfs_debug_init}, {
1764 "dilookup", DEBUG_I_LOOKUP, &devfs_debug_init}, {
1765 "diunlink", DEBUG_I_UNLINK, &devfs_debug_init},
1766#endif /* CONFIG_DEVFS_DEBUG */
1767 {
1768 "mount", OPTION_MOUNT, &boot_options}, {
1769 NULL, 0, NULL}
1770 };
1771
1772 while ((*str != '\0') && !isspace(*str)) {
1773 int i, found = 0, invert = 0;
1774
1775 if (strncmp(str, "no", 2) == 0) {
1776 invert = 1;
1777 str += 2;
1778 }
1779 for (i = 0; devfs_options_tab[i].name != NULL; i++) {
1780 int len = strlen(devfs_options_tab[i].name);
1781
1782 if (strncmp(str, devfs_options_tab[i].name, len) == 0) {
1783 if (invert)
1784 *devfs_options_tab[i].opt &=
1785 ~devfs_options_tab[i].mask;
1786 else
1787 *devfs_options_tab[i].opt |=
1788 devfs_options_tab[i].mask;
1789 str += len;
1790 found = 1;
1791 break;
1792 }
1793 }
1794 if (!found)
1795 return 0; /* No match */
1796 if (*str != ',')
1797 return 0; /* No more options */
1798 ++str;
1799 }
1800 return 1;
1801} /* End Function devfs_setup */
1802
1803__setup("devfs=", devfs_setup);
1804
1805EXPORT_SYMBOL(devfs_mk_dir);
1806EXPORT_SYMBOL(devfs_remove);
1807
1808/**
1809 * try_modload - Notify devfsd of an inode lookup by a non-devfsd process.
1810 * @parent: The parent devfs entry.
1811 * @fs_info: The filesystem info.
1812 * @name: The device name.
1813 * @namelen: The number of characters in @name.
1814 * @buf: A working area that will be used. This must not go out of scope
1815 * until devfsd is idle again.
1816 *
1817 * Returns 0 on success (event was queued), else a negative error code.
1818 */
1819
1820static int try_modload(struct devfs_entry *parent, struct fs_info *fs_info,
1821 const char *name, unsigned namelen,
1822 struct devfs_entry *buf)
1823{
1824 if (!(fs_info->devfsd_event_mask & (1 << DEVFSD_NOTIFY_LOOKUP)))
1825 return -ENOENT;
1826 if (is_devfsd_or_child(fs_info))
1827 return -ENOENT;
1828 memset(buf, 0, sizeof *buf);
1829 atomic_set(&buf->refcount, 1);
1830 buf->parent = parent;
1831 buf->namelen = namelen;
1832 buf->u.name = name;
1833 WRITE_ENTRY_MAGIC(buf, MAGIC_VALUE);
1834 if (!devfsd_notify_de(buf, DEVFSD_NOTIFY_LOOKUP, 0,
1835 current->euid, current->egid, fs_info))
1836 return -ENOENT;
1837 /* Possible success: event has been queued */
1838 return 0;
1839} /* End Function try_modload */
1840
1841/* Superblock operations follow */
1842
1843static struct inode_operations devfs_iops;
1844static struct inode_operations devfs_dir_iops;
1845static const struct file_operations devfs_fops;
1846static const struct file_operations devfs_dir_fops;
1847static struct inode_operations devfs_symlink_iops;
1848
1849static int devfs_notify_change(struct dentry *dentry, struct iattr *iattr)
1850{
1851 int retval;
1852 struct devfs_entry *de;
1853 struct inode *inode = dentry->d_inode;
1854 struct fs_info *fs_info = inode->i_sb->s_fs_info;
1855
1856 de = get_devfs_entry_from_vfs_inode(inode);
1857 if (de == NULL)
1858 return -ENODEV;
1859 retval = inode_change_ok(inode, iattr);
1860 if (retval != 0)
1861 return retval;
1862 retval = inode_setattr(inode, iattr);
1863 if (retval != 0)
1864 return retval;
1865 DPRINTK(DEBUG_I_CHANGE, "(%d): VFS inode: %p devfs_entry: %p\n",
1866 (int)inode->i_ino, inode, de);
1867 DPRINTK(DEBUG_I_CHANGE, "(): mode: 0%o uid: %d gid: %d\n",
1868 (int)inode->i_mode, (int)inode->i_uid, (int)inode->i_gid);
1869 /* Inode is not on hash chains, thus must save permissions here rather
1870 than in a write_inode() method */
1871 de->mode = inode->i_mode;
1872 de->inode.uid = inode->i_uid;
1873 de->inode.gid = inode->i_gid;
1874 de->inode.atime = inode->i_atime;
1875 de->inode.mtime = inode->i_mtime;
1876 de->inode.ctime = inode->i_ctime;
1877 if ((iattr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID)) &&
1878 !is_devfsd_or_child(fs_info))
1879 devfsd_notify_de(de, DEVFSD_NOTIFY_CHANGE, inode->i_mode,
1880 inode->i_uid, inode->i_gid, fs_info);
1881 return 0;
1882} /* End Function devfs_notify_change */
1883
1884static struct super_operations devfs_sops = {
1885 .drop_inode = generic_delete_inode,
1886 .statfs = simple_statfs,
1887};
1888
1889/**
1890 * _devfs_get_vfs_inode - Get a VFS inode.
1891 * @sb: The super block.
1892 * @de: The devfs inode.
1893 * @dentry: The dentry to register with the devfs inode.
1894 *
1895 * Returns the inode on success, else %NULL. An implicit devfs_get() is
1896 * performed if the inode is created.
1897 */
1898
1899static struct inode *_devfs_get_vfs_inode(struct super_block *sb,
1900 struct devfs_entry *de,
1901 struct dentry *dentry)
1902{
1903 struct inode *inode;
1904
1905 if (de->prev == de)
1906 return NULL; /* Quick check to see if unhooked */
1907 if ((inode = new_inode(sb)) == NULL) {
1908 PRINTK("(%s): new_inode() failed, de: %p\n", de->name, de);
1909 return NULL;
1910 }
1911 if (de->parent) {
1912 read_lock(&de->parent->u.dir.lock);
1913 if (de->prev != de)
1914 de->inode.dentry = dentry; /* Not unhooked */
1915 read_unlock(&de->parent->u.dir.lock);
1916 } else
1917 de->inode.dentry = dentry; /* Root: no locking needed */
1918 if (de->inode.dentry != dentry) { /* Must have been unhooked */
1919 iput(inode);
1920 return NULL;
1921 }
1922 /* FIXME where is devfs_put? */
1923 inode->u.generic_ip = devfs_get(de);
1924 inode->i_ino = de->inode.ino;
1925 DPRINTK(DEBUG_I_GET, "(%d): VFS inode: %p devfs_entry: %p\n",
1926 (int)inode->i_ino, inode, de);
1927 inode->i_blocks = 0;
1928 inode->i_blksize = FAKE_BLOCK_SIZE;
1929 inode->i_op = &devfs_iops;
1930 inode->i_mode = de->mode;
1931 if (S_ISDIR(de->mode)) {
1932 inode->i_op = &devfs_dir_iops;
1933 inode->i_fop = &devfs_dir_fops;
1934 } else if (S_ISLNK(de->mode)) {
1935 inode->i_op = &devfs_symlink_iops;
1936 inode->i_size = de->u.symlink.length;
1937 } else if (S_ISCHR(de->mode) || S_ISBLK(de->mode)) {
1938 init_special_inode(inode, de->mode, de->u.dev);
1939 } else if (S_ISFIFO(de->mode) || S_ISSOCK(de->mode)) {
1940 init_special_inode(inode, de->mode, 0);
1941 } else {
1942 PRINTK("(%s): unknown mode %o de: %p\n",
1943 de->name, de->mode, de);
1944 iput(inode);
1945 devfs_put(de);
1946 return NULL;
1947 }
1948
1949 inode->i_uid = de->inode.uid;
1950 inode->i_gid = de->inode.gid;
1951 inode->i_atime = de->inode.atime;
1952 inode->i_mtime = de->inode.mtime;
1953 inode->i_ctime = de->inode.ctime;
1954 DPRINTK(DEBUG_I_GET, "(): mode: 0%o uid: %d gid: %d\n",
1955 (int)inode->i_mode, (int)inode->i_uid, (int)inode->i_gid);
1956 return inode;
1957} /* End Function _devfs_get_vfs_inode */
1958
1959/* File operations for device entries follow */
1960
1961static int devfs_readdir(struct file *file, void *dirent, filldir_t filldir)
1962{
1963 int err, count;
1964 int stored = 0;
1965 struct fs_info *fs_info;
1966 struct devfs_entry *parent, *de, *next = NULL;
1967 struct inode *inode = file->f_dentry->d_inode;
1968
1969 fs_info = inode->i_sb->s_fs_info;
1970 parent = get_devfs_entry_from_vfs_inode(file->f_dentry->d_inode);
1971 if ((long)file->f_pos < 0)
1972 return -EINVAL;
1973 DPRINTK(DEBUG_F_READDIR, "(%s): fs_info: %p pos: %ld\n",
1974 parent->name, fs_info, (long)file->f_pos);
1975 switch ((long)file->f_pos) {
1976 case 0:
1977 err = (*filldir) (dirent, "..", 2, file->f_pos,
1978 parent_ino(file->f_dentry), DT_DIR);
1979 if (err == -EINVAL)
1980 break;
1981 if (err < 0)
1982 return err;
1983 file->f_pos++;
1984 ++stored;
1985 /* Fall through */
1986 case 1:
1987 err =
1988 (*filldir) (dirent, ".", 1, file->f_pos, inode->i_ino,
1989 DT_DIR);
1990 if (err == -EINVAL)
1991 break;
1992 if (err < 0)
1993 return err;
1994 file->f_pos++;
1995 ++stored;
1996 /* Fall through */
1997 default:
1998 /* Skip entries */
1999 count = file->f_pos - 2;
2000 read_lock(&parent->u.dir.lock);
2001 for (de = parent->u.dir.first; de && (count > 0); de = de->next)
2002 --count;
2003 devfs_get(de);
2004 read_unlock(&parent->u.dir.lock);
2005 /* Now add all remaining entries */
2006 while (de) {
2007 err = (*filldir) (dirent, de->name, de->namelen,
2008 file->f_pos, de->inode.ino,
2009 de->mode >> 12);
2010 if (err < 0)
2011 devfs_put(de);
2012 else {
2013 file->f_pos++;
2014 ++stored;
2015 }
2016 if (err == -EINVAL)
2017 break;
2018 if (err < 0)
2019 return err;
2020 read_lock(&parent->u.dir.lock);
2021 next = devfs_get(de->next);
2022 read_unlock(&parent->u.dir.lock);
2023 devfs_put(de);
2024 de = next;
2025 }
2026 break;
2027 }
2028 return stored;
2029} /* End Function devfs_readdir */
2030
2031/* Open devfs specific special files */
2032static int devfs_open(struct inode *inode, struct file *file)
2033{
2034 int err;
2035 int minor = MINOR(inode->i_rdev);
2036 struct file_operations *old_fops, *new_fops;
2037
2038 switch (minor) {
2039 case 0: /* /dev/.devfsd */
2040 new_fops = fops_get(&devfsd_fops);
2041 break;
2042#ifdef CONFIG_DEVFS_DEBUG
2043 case 1: /* /dev/.stat */
2044 new_fops = fops_get(&stat_fops);
2045 break;
2046#endif
2047 default:
2048 return -ENODEV;
2049 }
2050
2051 if (new_fops == NULL)
2052 return -ENODEV;
2053 old_fops = file->f_op;
2054 file->f_op = new_fops;
2055 err = new_fops->open ? new_fops->open(inode, file) : 0;
2056 if (err) {
2057 file->f_op = old_fops;
2058 fops_put(new_fops);
2059 } else
2060 fops_put(old_fops);
2061 return err;
2062} /* End Function devfs_open */
2063
2064static const struct file_operations devfs_fops = {
2065 .open = devfs_open,
2066};
2067
2068static const struct file_operations devfs_dir_fops = {
2069 .read = generic_read_dir,
2070 .readdir = devfs_readdir,
2071};
2072
2073/* Dentry operations for device entries follow */
2074
2075/**
2076 * devfs_d_release - Callback for when a dentry is freed.
2077 * @dentry: The dentry.
2078 */
2079
2080static void devfs_d_release(struct dentry *dentry)
2081{
2082 DPRINTK(DEBUG_D_RELEASE, "(%p): inode: %p\n", dentry, dentry->d_inode);
2083} /* End Function devfs_d_release */
2084
2085/**
2086 * devfs_d_iput - Callback for when a dentry loses its inode.
2087 * @dentry: The dentry.
2088 * @inode: The inode.
2089 */
2090
2091static void devfs_d_iput(struct dentry *dentry, struct inode *inode)
2092{
2093 struct devfs_entry *de;
2094
2095 de = get_devfs_entry_from_vfs_inode(inode);
2096 DPRINTK(DEBUG_D_IPUT,
2097 "(%s): dentry: %p inode: %p de: %p de->dentry: %p\n", de->name,
2098 dentry, inode, de, de->inode.dentry);
2099 if (de->inode.dentry && (de->inode.dentry != dentry))
2100 OOPS("(%s): de: %p dentry: %p de->dentry: %p\n",
2101 de->name, de, dentry, de->inode.dentry);
2102 de->inode.dentry = NULL;
2103 iput(inode);
2104 devfs_put(de);
2105} /* End Function devfs_d_iput */
2106
2107static int devfs_d_delete(struct dentry *dentry);
2108
2109static struct dentry_operations devfs_dops = {
2110 .d_delete = devfs_d_delete,
2111 .d_release = devfs_d_release,
2112 .d_iput = devfs_d_iput,
2113};
2114
2115static int devfs_d_revalidate_wait(struct dentry *dentry, struct nameidata *);
2116
2117static struct dentry_operations devfs_wait_dops = {
2118 .d_delete = devfs_d_delete,
2119 .d_release = devfs_d_release,
2120 .d_iput = devfs_d_iput,
2121 .d_revalidate = devfs_d_revalidate_wait,
2122};
2123
2124/**
2125 * devfs_d_delete - Callback for when all files for a dentry are closed.
2126 * @dentry: The dentry.
2127 */
2128
2129static int devfs_d_delete(struct dentry *dentry)
2130{
2131 struct inode *inode = dentry->d_inode;
2132
2133 if (dentry->d_op == &devfs_wait_dops)
2134 dentry->d_op = &devfs_dops;
2135 /* Unhash dentry if negative (has no inode) */
2136 if (inode == NULL) {
2137 DPRINTK(DEBUG_D_DELETE, "(%p): dropping negative dentry\n",
2138 dentry);
2139 return 1;
2140 }
2141 return 0;
2142} /* End Function devfs_d_delete */
2143
2144struct devfs_lookup_struct {
2145 devfs_handle_t de;
2146 wait_queue_head_t wait_queue;
2147};
2148
2149/* XXX: this doesn't handle the case where we got a negative dentry
2150 but a devfs entry has been registered in the meanwhile */
2151static int devfs_d_revalidate_wait(struct dentry *dentry, struct nameidata *nd)
2152{
2153 struct inode *dir = dentry->d_parent->d_inode;
2154 struct fs_info *fs_info = dir->i_sb->s_fs_info;
2155 devfs_handle_t parent = get_devfs_entry_from_vfs_inode(dir);
2156 struct devfs_lookup_struct *lookup_info = dentry->d_fsdata;
2157 DECLARE_WAITQUEUE(wait, current);
2158 int need_lock;
2159
2160 /*
2161 * FIXME HACK
2162 *
2163 * make sure that
2164 * d_instantiate always runs under lock
2165 * we release i_mutex lock before going to sleep
2166 *
2167 * unfortunately sometimes d_revalidate is called with
2168 * and sometimes without i_mutex lock held. The following checks
2169 * attempt to deduce when we need to add (and drop resp.) lock
2170 * here. This relies on current (2.6.2) calling coventions:
2171 *
2172 * lookup_hash is always run under i_mutex and is passing NULL
2173 * as nd
2174 *
2175 * open(...,O_CREATE,...) calls _lookup_hash under i_mutex
2176 * and sets flags to LOOKUP_OPEN|LOOKUP_CREATE
2177 *
2178 * all other invocations of ->d_revalidate seem to happen
2179 * outside of i_mutex
2180 */
2181 need_lock = nd &&
2182 (!(nd->flags & LOOKUP_CREATE) || (nd->flags & LOOKUP_PARENT));
2183
2184 if (need_lock)
2185 mutex_lock(&dir->i_mutex);
2186
2187 if (is_devfsd_or_child(fs_info)) {
2188 devfs_handle_t de = lookup_info->de;
2189 struct inode *inode;
2190
2191 DPRINTK(DEBUG_I_LOOKUP,
2192 "(%s): dentry: %p inode: %p de: %p by: \"%s\"\n",
2193 dentry->d_name.name, dentry, dentry->d_inode, de,
2194 current->comm);
2195 if (dentry->d_inode)
2196 goto out;
2197 if (de == NULL) {
2198 read_lock(&parent->u.dir.lock);
2199 de = _devfs_search_dir(parent, dentry->d_name.name,
2200 dentry->d_name.len);
2201 read_unlock(&parent->u.dir.lock);
2202 if (de == NULL)
2203 goto out;
2204 lookup_info->de = de;
2205 }
2206 /* Create an inode, now that the driver information is available */
2207 inode = _devfs_get_vfs_inode(dir->i_sb, de, dentry);
2208 if (!inode)
2209 goto out;
2210 DPRINTK(DEBUG_I_LOOKUP,
2211 "(%s): new VFS inode(%u): %p de: %p by: \"%s\"\n",
2212 de->name, de->inode.ino, inode, de, current->comm);
2213 d_instantiate(dentry, inode);
2214 goto out;
2215 }
2216 if (lookup_info == NULL)
2217 goto out; /* Early termination */
2218 read_lock(&parent->u.dir.lock);
2219 if (dentry->d_fsdata) {
2220 set_current_state(TASK_UNINTERRUPTIBLE);
2221 add_wait_queue(&lookup_info->wait_queue, &wait);
2222 read_unlock(&parent->u.dir.lock);
2223 /* at this point it is always (hopefully) locked */
2224 mutex_unlock(&dir->i_mutex);
2225 schedule();
2226 mutex_lock(&dir->i_mutex);
2227 /*
2228 * This does not need nor should remove wait from wait_queue.
2229 * Wait queue head is never reused - nothing is ever added to it
2230 * after all waiters have been waked up and head itself disappears
2231 * very soon after it. Moreover it is local variable on stack that
2232 * is likely to have already disappeared so any reference to it
2233 * at this point is buggy.
2234 */
2235
2236 } else
2237 read_unlock(&parent->u.dir.lock);
2238
2239 out:
2240 if (need_lock)
2241 mutex_unlock(&dir->i_mutex);
2242 return 1;
2243} /* End Function devfs_d_revalidate_wait */
2244
2245/* Inode operations for device entries follow */
2246
2247static struct dentry *devfs_lookup(struct inode *dir, struct dentry *dentry,
2248 struct nameidata *nd)
2249{
2250 struct devfs_entry tmp; /* Must stay in scope until devfsd idle again */
2251 struct devfs_lookup_struct lookup_info;
2252 struct fs_info *fs_info = dir->i_sb->s_fs_info;
2253 struct devfs_entry *parent, *de;
2254 struct inode *inode;
2255 struct dentry *retval = NULL;
2256
2257 /* Set up the dentry operations before anything else, to ensure cleaning
2258 up on any error */
2259 dentry->d_op = &devfs_dops;
2260 /* First try to get the devfs entry for this directory */
2261 parent = get_devfs_entry_from_vfs_inode(dir);
2262 DPRINTK(DEBUG_I_LOOKUP, "(%s): dentry: %p parent: %p by: \"%s\"\n",
2263 dentry->d_name.name, dentry, parent, current->comm);
2264 if (parent == NULL)
2265 return ERR_PTR(-ENOENT);
2266 read_lock(&parent->u.dir.lock);
2267 de = _devfs_search_dir(parent, dentry->d_name.name, dentry->d_name.len);
2268 read_unlock(&parent->u.dir.lock);
2269 lookup_info.de = de;
2270 init_waitqueue_head(&lookup_info.wait_queue);
2271 dentry->d_fsdata = &lookup_info;
2272 if (de == NULL) { /* Try with devfsd. For any kind of failure, leave a negative dentry
2273 so someone else can deal with it (in the case where the sysadmin
2274 does a mknod()). It's important to do this before hashing the
2275 dentry, so that the devfsd queue is filled before revalidates
2276 can start */
2277 if (try_modload(parent, fs_info, dentry->d_name.name, dentry->d_name.len, &tmp) < 0) { /* Lookup event was not queued to devfsd */
2278 d_add(dentry, NULL);
2279 return NULL;
2280 }
2281 }
2282 dentry->d_op = &devfs_wait_dops;
2283 d_add(dentry, NULL); /* Open the floodgates */
2284 /* Unlock directory semaphore, which will release any waiters. They
2285 will get the hashed dentry, and may be forced to wait for
2286 revalidation */
2287 mutex_unlock(&dir->i_mutex);
2288 wait_for_devfsd_finished(fs_info); /* If I'm not devfsd, must wait */
2289 mutex_lock(&dir->i_mutex); /* Grab it again because them's the rules */
2290 de = lookup_info.de;
2291 /* If someone else has been so kind as to make the inode, we go home
2292 early */
2293 if (dentry->d_inode)
2294 goto out;
2295 if (de == NULL) {
2296 read_lock(&parent->u.dir.lock);
2297 de = _devfs_search_dir(parent, dentry->d_name.name,
2298 dentry->d_name.len);
2299 read_unlock(&parent->u.dir.lock);
2300 if (de == NULL)
2301 goto out;
2302 /* OK, there's an entry now, but no VFS inode yet */
2303 }
2304 /* Create an inode, now that the driver information is available */
2305 inode = _devfs_get_vfs_inode(dir->i_sb, de, dentry);
2306 if (!inode) {
2307 retval = ERR_PTR(-ENOMEM);
2308 goto out;
2309 }
2310 DPRINTK(DEBUG_I_LOOKUP,
2311 "(%s): new VFS inode(%u): %p de: %p by: \"%s\"\n", de->name,
2312 de->inode.ino, inode, de, current->comm);
2313 d_instantiate(dentry, inode);
2314 out:
2315 write_lock(&parent->u.dir.lock);
2316 dentry->d_op = &devfs_dops;
2317 dentry->d_fsdata = NULL;
2318 wake_up(&lookup_info.wait_queue);
2319 write_unlock(&parent->u.dir.lock);
2320 devfs_put(de);
2321 return retval;
2322} /* End Function devfs_lookup */
2323
2324static int devfs_unlink(struct inode *dir, struct dentry *dentry)
2325{
2326 int unhooked;
2327 struct devfs_entry *de;
2328 struct inode *inode = dentry->d_inode;
2329 struct fs_info *fs_info = dir->i_sb->s_fs_info;
2330
2331 de = get_devfs_entry_from_vfs_inode(inode);
2332 DPRINTK(DEBUG_I_UNLINK, "(%s): de: %p\n", dentry->d_name.name, de);
2333 if (de == NULL)
2334 return -ENOENT;
2335 if (!de->vfs)
2336 return -EPERM;
2337 write_lock(&de->parent->u.dir.lock);
2338 unhooked = _devfs_unhook(de);
2339 write_unlock(&de->parent->u.dir.lock);
2340 if (!unhooked)
2341 return -ENOENT;
2342 if (!is_devfsd_or_child(fs_info))
2343 devfsd_notify_de(de, DEVFSD_NOTIFY_DELETE, inode->i_mode,
2344 inode->i_uid, inode->i_gid, fs_info);
2345 free_dentry(de);
2346 devfs_put(de);
2347 return 0;
2348} /* End Function devfs_unlink */
2349
2350static int devfs_symlink(struct inode *dir, struct dentry *dentry,
2351 const char *symname)
2352{
2353 int err;
2354 struct fs_info *fs_info = dir->i_sb->s_fs_info;
2355 struct devfs_entry *parent, *de;
2356 struct inode *inode;
2357
2358 /* First try to get the devfs entry for this directory */
2359 parent = get_devfs_entry_from_vfs_inode(dir);
2360 if (parent == NULL)
2361 return -ENOENT;
2362 err = devfs_do_symlink(parent, dentry->d_name.name, symname, &de);
2363 DPRINTK(DEBUG_DISABLED, "(%s): errcode from <devfs_do_symlink>: %d\n",
2364 dentry->d_name.name, err);
2365 if (err < 0)
2366 return err;
2367 de->vfs = TRUE;
2368 de->inode.uid = current->euid;
2369 de->inode.gid = current->egid;
2370 de->inode.atime = CURRENT_TIME;
2371 de->inode.mtime = CURRENT_TIME;
2372 de->inode.ctime = CURRENT_TIME;
2373 if ((inode = _devfs_get_vfs_inode(dir->i_sb, de, dentry)) == NULL)
2374 return -ENOMEM;
2375 DPRINTK(DEBUG_DISABLED, "(%s): new VFS inode(%u): %p dentry: %p\n",
2376 dentry->d_name.name, de->inode.ino, inode, dentry);
2377 d_instantiate(dentry, inode);
2378 if (!is_devfsd_or_child(fs_info))
2379 devfsd_notify_de(de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
2380 inode->i_uid, inode->i_gid, fs_info);
2381 return 0;
2382} /* End Function devfs_symlink */
2383
2384static int devfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
2385{
2386 int err;
2387 struct fs_info *fs_info = dir->i_sb->s_fs_info;
2388 struct devfs_entry *parent, *de;
2389 struct inode *inode;
2390
2391 mode = (mode & ~S_IFMT) | S_IFDIR; /* VFS doesn't pass S_IFMT part */
2392 parent = get_devfs_entry_from_vfs_inode(dir);
2393 if (parent == NULL)
2394 return -ENOENT;
2395 de = _devfs_alloc_entry(dentry->d_name.name, dentry->d_name.len, mode);
2396 if (!de)
2397 return -ENOMEM;
2398 de->vfs = TRUE;
2399 if ((err = _devfs_append_entry(parent, de, NULL)) != 0)
2400 return err;
2401 de->inode.uid = current->euid;
2402 de->inode.gid = current->egid;
2403 de->inode.atime = CURRENT_TIME;
2404 de->inode.mtime = CURRENT_TIME;
2405 de->inode.ctime = CURRENT_TIME;
2406 if ((inode = _devfs_get_vfs_inode(dir->i_sb, de, dentry)) == NULL)
2407 return -ENOMEM;
2408 DPRINTK(DEBUG_DISABLED, "(%s): new VFS inode(%u): %p dentry: %p\n",
2409 dentry->d_name.name, de->inode.ino, inode, dentry);
2410 d_instantiate(dentry, inode);
2411 if (!is_devfsd_or_child(fs_info))
2412 devfsd_notify_de(de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
2413 inode->i_uid, inode->i_gid, fs_info);
2414 return 0;
2415} /* End Function devfs_mkdir */
2416
2417static int devfs_rmdir(struct inode *dir, struct dentry *dentry)
2418{
2419 int err = 0;
2420 struct devfs_entry *de;
2421 struct fs_info *fs_info = dir->i_sb->s_fs_info;
2422 struct inode *inode = dentry->d_inode;
2423
2424 if (dir->i_sb->s_fs_info != inode->i_sb->s_fs_info)
2425 return -EINVAL;
2426 de = get_devfs_entry_from_vfs_inode(inode);
2427 if (de == NULL)
2428 return -ENOENT;
2429 if (!S_ISDIR(de->mode))
2430 return -ENOTDIR;
2431 if (!de->vfs)
2432 return -EPERM;
2433 /* First ensure the directory is empty and will stay that way */
2434 write_lock(&de->u.dir.lock);
2435 if (de->u.dir.first)
2436 err = -ENOTEMPTY;
2437 else
2438 de->u.dir.no_more_additions = TRUE;
2439 write_unlock(&de->u.dir.lock);
2440 if (err)
2441 return err;
2442 /* Now unhook the directory from its parent */
2443 write_lock(&de->parent->u.dir.lock);
2444 if (!_devfs_unhook(de))
2445 err = -ENOENT;
2446 write_unlock(&de->parent->u.dir.lock);
2447 if (err)
2448 return err;
2449 if (!is_devfsd_or_child(fs_info))
2450 devfsd_notify_de(de, DEVFSD_NOTIFY_DELETE, inode->i_mode,
2451 inode->i_uid, inode->i_gid, fs_info);
2452 free_dentry(de);
2453 devfs_put(de);
2454 return 0;
2455} /* End Function devfs_rmdir */
2456
2457static int devfs_mknod(struct inode *dir, struct dentry *dentry, int mode,
2458 dev_t rdev)
2459{
2460 int err;
2461 struct fs_info *fs_info = dir->i_sb->s_fs_info;
2462 struct devfs_entry *parent, *de;
2463 struct inode *inode;
2464
2465 DPRINTK(DEBUG_I_MKNOD, "(%s): mode: 0%o dev: %u:%u\n",
2466 dentry->d_name.name, mode, MAJOR(rdev), MINOR(rdev));
2467 parent = get_devfs_entry_from_vfs_inode(dir);
2468 if (parent == NULL)
2469 return -ENOENT;
2470 de = _devfs_alloc_entry(dentry->d_name.name, dentry->d_name.len, mode);
2471 if (!de)
2472 return -ENOMEM;
2473 de->vfs = TRUE;
2474 if (S_ISCHR(mode) || S_ISBLK(mode))
2475 de->u.dev = rdev;
2476 if ((err = _devfs_append_entry(parent, de, NULL)) != 0)
2477 return err;
2478 de->inode.uid = current->euid;
2479 de->inode.gid = current->egid;
2480 de->inode.atime = CURRENT_TIME;
2481 de->inode.mtime = CURRENT_TIME;
2482 de->inode.ctime = CURRENT_TIME;
2483 if ((inode = _devfs_get_vfs_inode(dir->i_sb, de, dentry)) == NULL)
2484 return -ENOMEM;
2485 DPRINTK(DEBUG_I_MKNOD, ": new VFS inode(%u): %p dentry: %p\n",
2486 de->inode.ino, inode, dentry);
2487 d_instantiate(dentry, inode);
2488 if (!is_devfsd_or_child(fs_info))
2489 devfsd_notify_de(de, DEVFSD_NOTIFY_CREATE, inode->i_mode,
2490 inode->i_uid, inode->i_gid, fs_info);
2491 return 0;
2492} /* End Function devfs_mknod */
2493
2494static void *devfs_follow_link(struct dentry *dentry, struct nameidata *nd)
2495{
2496 struct devfs_entry *p = get_devfs_entry_from_vfs_inode(dentry->d_inode);
2497 nd_set_link(nd, p ? p->u.symlink.linkname : ERR_PTR(-ENODEV));
2498 return NULL;
2499} /* End Function devfs_follow_link */
2500
2501static struct inode_operations devfs_iops = {
2502 .setattr = devfs_notify_change,
2503};
2504
2505static struct inode_operations devfs_dir_iops = {
2506 .lookup = devfs_lookup,
2507 .unlink = devfs_unlink,
2508 .symlink = devfs_symlink,
2509 .mkdir = devfs_mkdir,
2510 .rmdir = devfs_rmdir,
2511 .mknod = devfs_mknod,
2512 .setattr = devfs_notify_change,
2513};
2514
2515static struct inode_operations devfs_symlink_iops = {
2516 .readlink = generic_readlink,
2517 .follow_link = devfs_follow_link,
2518 .setattr = devfs_notify_change,
2519};
2520
2521static int devfs_fill_super(struct super_block *sb, void *data, int silent)
2522{
2523 struct inode *root_inode = NULL;
2524
2525 if (_devfs_get_root_entry() == NULL)
2526 goto out_no_root;
2527 atomic_set(&fs_info.devfsd_overrun_count, 0);
2528 init_waitqueue_head(&fs_info.devfsd_wait_queue);
2529 init_waitqueue_head(&fs_info.revalidate_wait_queue);
2530 fs_info.sb = sb;
2531 sb->s_fs_info = &fs_info;
2532 sb->s_blocksize = 1024;
2533 sb->s_blocksize_bits = 10;
2534 sb->s_magic = DEVFS_SUPER_MAGIC;
2535 sb->s_op = &devfs_sops;
2536 sb->s_time_gran = 1;
2537 if ((root_inode = _devfs_get_vfs_inode(sb, root_entry, NULL)) == NULL)
2538 goto out_no_root;
2539 sb->s_root = d_alloc_root(root_inode);
2540 if (!sb->s_root)
2541 goto out_no_root;
2542 DPRINTK(DEBUG_S_READ, "(): made devfs ptr: %p\n", sb->s_fs_info);
2543 return 0;
2544
2545 out_no_root:
2546 PRINTK("(): get root inode failed\n");
2547 if (root_inode)
2548 iput(root_inode);
2549 return -EINVAL;
2550} /* End Function devfs_fill_super */
2551
2552static int devfs_get_sb(struct file_system_type *fs_type,
2553 int flags, const char *dev_name,
2554 void *data, struct vfsmount *mnt)
2555{
2556 return get_sb_single(fs_type, flags, data, devfs_fill_super, mnt);
2557}
2558
2559static struct file_system_type devfs_fs_type = {
2560 .name = DEVFS_NAME,
2561 .get_sb = devfs_get_sb,
2562 .kill_sb = kill_anon_super,
2563};
2564
2565/* File operations for devfsd follow */
2566
2567static ssize_t devfsd_read(struct file *file, char __user *buf, size_t len,
2568 loff_t * ppos)
2569{
2570 int done = FALSE;
2571 int ival;
2572 loff_t pos, devname_offset, tlen, rpos;
2573 devfs_handle_t de;
2574 struct devfsd_buf_entry *entry;
2575 struct fs_info *fs_info = file->f_dentry->d_inode->i_sb->s_fs_info;
2576 struct devfsd_notify_struct *info = fs_info->devfsd_info;
2577 DECLARE_WAITQUEUE(wait, current);
2578
2579 /* Verify the task has grabbed the queue */
2580 if (fs_info->devfsd_task != current)
2581 return -EPERM;
2582 info->major = 0;
2583 info->minor = 0;
2584 /* Block for a new entry */
2585 set_current_state(TASK_INTERRUPTIBLE);
2586 add_wait_queue(&fs_info->devfsd_wait_queue, &wait);
2587 while (devfsd_queue_empty(fs_info)) {
2588 fs_info->devfsd_sleeping = TRUE;
2589 wake_up(&fs_info->revalidate_wait_queue);
2590 schedule();
2591 fs_info->devfsd_sleeping = FALSE;
2592 if (signal_pending(current)) {
2593 remove_wait_queue(&fs_info->devfsd_wait_queue, &wait);
2594 __set_current_state(TASK_RUNNING);
2595 return -EINTR;
2596 }
2597 set_current_state(TASK_INTERRUPTIBLE);
2598 }
2599 remove_wait_queue(&fs_info->devfsd_wait_queue, &wait);
2600 __set_current_state(TASK_RUNNING);
2601 /* Now play with the data */
2602 ival = atomic_read(&fs_info->devfsd_overrun_count);
2603 info->overrun_count = ival;
2604 entry = fs_info->devfsd_first_event;
2605 info->type = entry->type;
2606 info->mode = entry->mode;
2607 info->uid = entry->uid;
2608 info->gid = entry->gid;
2609 de = entry->de;
2610 if (S_ISCHR(de->mode) || S_ISBLK(de->mode)) {
2611 info->major = MAJOR(de->u.dev);
2612 info->minor = MINOR(de->u.dev);
2613 }
2614 pos = devfs_generate_path(de, info->devname, DEVFS_PATHLEN);
2615 if (pos < 0)
2616 return pos;
2617 info->namelen = DEVFS_PATHLEN - pos - 1;
2618 if (info->mode == 0)
2619 info->mode = de->mode;
2620 devname_offset = info->devname - (char *)info;
2621 rpos = *ppos;
2622 if (rpos < devname_offset) {
2623 /* Copy parts of the header */
2624 tlen = devname_offset - rpos;
2625 if (tlen > len)
2626 tlen = len;
2627 if (copy_to_user(buf, (char *)info + rpos, tlen)) {
2628 return -EFAULT;
2629 }
2630 rpos += tlen;
2631 buf += tlen;
2632 len -= tlen;
2633 }
2634 if ((rpos >= devname_offset) && (len > 0)) {
2635 /* Copy the name */
2636 tlen = info->namelen + 1;
2637 if (tlen > len)
2638 tlen = len;
2639 else
2640 done = TRUE;
2641 if (copy_to_user
2642 (buf, info->devname + pos + rpos - devname_offset, tlen)) {
2643 return -EFAULT;
2644 }
2645 rpos += tlen;
2646 }
2647 tlen = rpos - *ppos;
2648 if (done) {
2649 devfs_handle_t parent;
2650
2651 spin_lock(&fs_info->devfsd_buffer_lock);
2652 fs_info->devfsd_first_event = entry->next;
2653 if (entry->next == NULL)
2654 fs_info->devfsd_last_event = NULL;
2655 spin_unlock(&fs_info->devfsd_buffer_lock);
2656 for (; de != NULL; de = parent) {
2657 parent = de->parent;
2658 devfs_put(de);
2659 }
2660 kmem_cache_free(devfsd_buf_cache, entry);
2661 if (ival > 0)
2662 atomic_sub(ival, &fs_info->devfsd_overrun_count);
2663 *ppos = 0;
2664 } else
2665 *ppos = rpos;
2666 return tlen;
2667} /* End Function devfsd_read */
2668
2669static int devfsd_ioctl(struct inode *inode, struct file *file,
2670 unsigned int cmd, unsigned long arg)
2671{
2672 int ival;
2673 struct fs_info *fs_info = inode->i_sb->s_fs_info;
2674
2675 switch (cmd) {
2676 case DEVFSDIOC_GET_PROTO_REV:
2677 ival = DEVFSD_PROTOCOL_REVISION_KERNEL;
2678 if (copy_to_user((void __user *)arg, &ival, sizeof ival))
2679 return -EFAULT;
2680 break;
2681 case DEVFSDIOC_SET_EVENT_MASK:
2682 /* Ensure only one reader has access to the queue. This scheme will
2683 work even if the global kernel lock were to be removed, because it
2684 doesn't matter who gets in first, as long as only one gets it */
2685 if (fs_info->devfsd_task == NULL) {
2686 static DEFINE_SPINLOCK(lock);
2687
2688 if (!spin_trylock(&lock))
2689 return -EBUSY;
2690 if (fs_info->devfsd_task != NULL) { /* We lost the race... */
2691 spin_unlock(&lock);
2692 return -EBUSY;
2693 }
2694 fs_info->devfsd_task = current;
2695 spin_unlock(&lock);
2696 fs_info->devfsd_pgrp =
2697 (process_group(current) ==
2698 current->pid) ? process_group(current) : 0;
2699 fs_info->devfsd_file = file;
2700 fs_info->devfsd_info =
2701 kmalloc(sizeof *fs_info->devfsd_info, GFP_KERNEL);
2702 if (!fs_info->devfsd_info) {
2703 devfsd_close(inode, file);
2704 return -ENOMEM;
2705 }
2706 } else if (fs_info->devfsd_task != current)
2707 return -EBUSY;
2708 fs_info->devfsd_event_mask = arg; /* Let the masses come forth */
2709 break;
2710 case DEVFSDIOC_RELEASE_EVENT_QUEUE:
2711 if (fs_info->devfsd_file != file)
2712 return -EPERM;
2713 return devfsd_close(inode, file);
2714 /*break; */
2715#ifdef CONFIG_DEVFS_DEBUG
2716 case DEVFSDIOC_SET_DEBUG_MASK:
2717 if (copy_from_user(&ival, (void __user *)arg, sizeof ival))
2718 return -EFAULT;
2719 devfs_debug = ival;
2720 break;
2721#endif
2722 default:
2723 return -ENOIOCTLCMD;
2724 }
2725 return 0;
2726} /* End Function devfsd_ioctl */
2727
2728static int devfsd_close(struct inode *inode, struct file *file)
2729{
2730 struct devfsd_buf_entry *entry, *next;
2731 struct fs_info *fs_info = inode->i_sb->s_fs_info;
2732
2733 if (fs_info->devfsd_file != file)
2734 return 0;
2735 fs_info->devfsd_event_mask = 0;
2736 fs_info->devfsd_file = NULL;
2737 spin_lock(&fs_info->devfsd_buffer_lock);
2738 entry = fs_info->devfsd_first_event;
2739 fs_info->devfsd_first_event = NULL;
2740 fs_info->devfsd_last_event = NULL;
2741 kfree(fs_info->devfsd_info);
2742 fs_info->devfsd_info = NULL;
2743 spin_unlock(&fs_info->devfsd_buffer_lock);
2744 fs_info->devfsd_pgrp = 0;
2745 fs_info->devfsd_task = NULL;
2746 wake_up(&fs_info->revalidate_wait_queue);
2747 for (; entry; entry = next) {
2748 next = entry->next;
2749 kmem_cache_free(devfsd_buf_cache, entry);
2750 }
2751 return 0;
2752} /* End Function devfsd_close */
2753
2754#ifdef CONFIG_DEVFS_DEBUG
2755static ssize_t stat_read(struct file *file, char __user *buf, size_t len,
2756 loff_t * ppos)
2757{
2758 ssize_t num;
2759 char txt[80];
2760
2761 num = sprintf(txt, "Number of entries: %u number of bytes: %u\n",
2762 stat_num_entries, stat_num_bytes) + 1;
2763 if (*ppos >= num)
2764 return 0;
2765 if (*ppos + len > num)
2766 len = num - *ppos;
2767 if (copy_to_user(buf, txt + *ppos, len))
2768 return -EFAULT;
2769 *ppos += len;
2770 return len;
2771} /* End Function stat_read */
2772#endif
2773
2774static int __init init_devfs_fs(void)
2775{
2776 int err;
2777 int major;
2778 struct devfs_entry *devfsd;
2779#ifdef CONFIG_DEVFS_DEBUG
2780 struct devfs_entry *stat;
2781#endif
2782
2783 if (_devfs_get_root_entry() == NULL)
2784 return -ENOMEM;
2785
2786 printk(KERN_INFO "%s: %s Richard Gooch (rgooch@atnf.csiro.au)\n",
2787 DEVFS_NAME, DEVFS_VERSION);
2788 devfsd_buf_cache = kmem_cache_create("devfsd_event",
2789 sizeof(struct devfsd_buf_entry),
2790 0, 0, NULL, NULL);
2791 if (!devfsd_buf_cache)
2792 OOPS("(): unable to allocate event slab\n");
2793#ifdef CONFIG_DEVFS_DEBUG
2794 devfs_debug = devfs_debug_init;
2795 printk(KERN_INFO "%s: devfs_debug: 0x%0x\n", DEVFS_NAME, devfs_debug);
2796#endif
2797 printk(KERN_INFO "%s: boot_options: 0x%0x\n", DEVFS_NAME, boot_options);
2798
2799 /* register special device for devfsd communication */
2800 major = register_chrdev(0, "devfs", &devfs_fops);
2801 if (major < 0)
2802 return major;
2803
2804 /* And create the entry for ".devfsd" */
2805 devfsd = _devfs_alloc_entry(".devfsd", 0, S_IFCHR | S_IRUSR | S_IWUSR);
2806 if (devfsd == NULL)
2807 return -ENOMEM;
2808 devfsd->u.dev = MKDEV(major, 0);
2809 _devfs_append_entry(root_entry, devfsd, NULL);
2810
2811#ifdef CONFIG_DEVFS_DEBUG
2812 stat = _devfs_alloc_entry(".stat", 0, S_IFCHR | S_IRUGO);
2813 if (stat == NULL)
2814 return -ENOMEM;
2815 stat->u.dev = MKDEV(major, 1);
2816 _devfs_append_entry(root_entry, stat, NULL);
2817#endif
2818
2819 err = register_filesystem(&devfs_fs_type);
2820 return err;
2821} /* End Function init_devfs_fs */
2822
2823void __init mount_devfs_fs(void)
2824{
2825 int err;
2826
2827 if (!(boot_options & OPTION_MOUNT))
2828 return;
2829 err = do_mount("none", "/dev", "devfs", 0, NULL);
2830 if (err == 0)
2831 printk(KERN_INFO "Mounted devfs on /dev\n");
2832 else
2833 PRINTK("(): unable to mount devfs, err: %d\n", err);
2834} /* End Function mount_devfs_fs */
2835
2836module_init(init_devfs_fs)
diff --git a/fs/devfs/util.c b/fs/devfs/util.c
deleted file mode 100644
index db06d388c9ac..000000000000
--- a/fs/devfs/util.c
+++ /dev/null
@@ -1,97 +0,0 @@
1/* devfs (Device FileSystem) utilities.
2
3 Copyright (C) 1999-2002 Richard Gooch
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free
17 Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19 Richard Gooch may be reached by email at rgooch@atnf.csiro.au
20 The postal address is:
21 Richard Gooch, c/o ATNF, P. O. Box 76, Epping, N.S.W., 2121, Australia.
22
23 ChangeLog
24
25 19991031 Richard Gooch <rgooch@atnf.csiro.au>
26 Created.
27 19991103 Richard Gooch <rgooch@atnf.csiro.au>
28 Created <_devfs_convert_name> and supported SCSI and IDE CD-ROMs
29 20000203 Richard Gooch <rgooch@atnf.csiro.au>
30 Changed operations pointer type to void *.
31 20000621 Richard Gooch <rgooch@atnf.csiro.au>
32 Changed interface to <devfs_register_series>.
33 20000622 Richard Gooch <rgooch@atnf.csiro.au>
34 Took account of interface change to <devfs_mk_symlink>.
35 Took account of interface change to <devfs_mk_dir>.
36 20010519 Richard Gooch <rgooch@atnf.csiro.au>
37 Documentation cleanup.
38 20010709 Richard Gooch <rgooch@atnf.csiro.au>
39 Created <devfs_*alloc_major> and <devfs_*alloc_devnum>.
40 20010710 Richard Gooch <rgooch@atnf.csiro.au>
41 Created <devfs_*alloc_unique_number>.
42 20010730 Richard Gooch <rgooch@atnf.csiro.au>
43 Documentation typo fix.
44 20010806 Richard Gooch <rgooch@atnf.csiro.au>
45 Made <block_semaphore> and <char_semaphore> private.
46 20010813 Richard Gooch <rgooch@atnf.csiro.au>
47 Fixed bug in <devfs_alloc_unique_number>: limited to 128 numbers
48 20010818 Richard Gooch <rgooch@atnf.csiro.au>
49 Updated major masks up to Linus' "no new majors" proclamation.
50 Block: were 126 now 122 free, char: were 26 now 19 free.
51 20020324 Richard Gooch <rgooch@atnf.csiro.au>
52 Fixed bug in <devfs_alloc_unique_number>: was clearing beyond
53 bitfield.
54 20020326 Richard Gooch <rgooch@atnf.csiro.au>
55 Fixed bitfield data type for <devfs_*alloc_devnum>.
56 Made major bitfield type and initialiser 64 bit safe.
57 20020413 Richard Gooch <rgooch@atnf.csiro.au>
58 Fixed shift warning on 64 bit machines.
59 20020428 Richard Gooch <rgooch@atnf.csiro.au>
60 Copied and used macro for error messages from fs/devfs/base.c
61 20021013 Richard Gooch <rgooch@atnf.csiro.au>
62 Documentation fix.
63 20030101 Adam J. Richter <adam@yggdrasil.com>
64 Eliminate DEVFS_SPECIAL_{CHR,BLK}. Use mode_t instead.
65 20030106 Christoph Hellwig <hch@infradead.org>
66 Rewrite devfs_{,de}alloc_devnum to look like C code.
67*/
68#include <linux/module.h>
69#include <linux/init.h>
70#include <linux/devfs_fs_kernel.h>
71#include <linux/slab.h>
72#include <linux/vmalloc.h>
73#include <linux/genhd.h>
74#include <linux/bitops.h>
75
76int devfs_register_tape(const char *name)
77{
78 char tname[32], dest[64];
79 static unsigned int tape_counter;
80 unsigned int n = tape_counter++;
81
82 sprintf(dest, "../%s", name);
83 sprintf(tname, "tapes/tape%u", n);
84 devfs_mk_symlink(tname, dest);
85
86 return n;
87}
88
89EXPORT_SYMBOL(devfs_register_tape);
90
91void devfs_unregister_tape(int num)
92{
93 if (num >= 0)
94 devfs_remove("tapes/tape%u", num);
95}
96
97EXPORT_SYMBOL(devfs_unregister_tape);
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 538fb0418fba..5981e17f46f0 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -220,7 +220,8 @@ static void dio_complete(struct dio *dio, loff_t offset, ssize_t bytes)
220 if (dio->end_io && dio->result) 220 if (dio->end_io && dio->result)
221 dio->end_io(dio->iocb, offset, bytes, dio->map_bh.b_private); 221 dio->end_io(dio->iocb, offset, bytes, dio->map_bh.b_private);
222 if (dio->lock_type == DIO_LOCKING) 222 if (dio->lock_type == DIO_LOCKING)
223 up_read(&dio->inode->i_alloc_sem); 223 /* lockdep: non-owner release */
224 up_read_non_owner(&dio->inode->i_alloc_sem);
224} 225}
225 226
226/* 227/*
@@ -1261,7 +1262,8 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
1261 } 1262 }
1262 1263
1263 if (dio_lock_type == DIO_LOCKING) 1264 if (dio_lock_type == DIO_LOCKING)
1264 down_read(&inode->i_alloc_sem); 1265 /* lockdep: not the owner will release it */
1266 down_read_non_owner(&inode->i_alloc_sem);
1265 } 1267 }
1266 1268
1267 /* 1269 /*
diff --git a/fs/efs/inode.c b/fs/efs/inode.c
index 180607f9314d..174696f9bf14 100644
--- a/fs/efs/inode.c
+++ b/fs/efs/inode.c
@@ -21,7 +21,7 @@ static sector_t _efs_bmap(struct address_space *mapping, sector_t block)
21{ 21{
22 return generic_block_bmap(mapping,block,efs_get_block); 22 return generic_block_bmap(mapping,block,efs_get_block);
23} 23}
24static struct address_space_operations efs_aops = { 24static const struct address_space_operations efs_aops = {
25 .readpage = efs_readpage, 25 .readpage = efs_readpage,
26 .sync_page = block_sync_page, 26 .sync_page = block_sync_page,
27 .bmap = _efs_bmap 27 .bmap = _efs_bmap
diff --git a/fs/efs/symlink.c b/fs/efs/symlink.c
index 3d9a350e3e7f..e249cf733a6b 100644
--- a/fs/efs/symlink.c
+++ b/fs/efs/symlink.c
@@ -53,6 +53,6 @@ fail:
53 return err; 53 return err;
54} 54}
55 55
56struct address_space_operations efs_symlink_aops = { 56const struct address_space_operations efs_symlink_aops = {
57 .readpage = efs_symlink_readpage 57 .readpage = efs_symlink_readpage
58}; 58};
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 9c677bbd0b08..19ffb043abbc 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -120,7 +120,7 @@ struct epoll_filefd {
120 */ 120 */
121struct wake_task_node { 121struct wake_task_node {
122 struct list_head llink; 122 struct list_head llink;
123 task_t *task; 123 struct task_struct *task;
124 wait_queue_head_t *wq; 124 wait_queue_head_t *wq;
125}; 125};
126 126
@@ -413,7 +413,7 @@ static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq)
413{ 413{
414 int wake_nests = 0; 414 int wake_nests = 0;
415 unsigned long flags; 415 unsigned long flags;
416 task_t *this_task = current; 416 struct task_struct *this_task = current;
417 struct list_head *lsthead = &psw->wake_task_list, *lnk; 417 struct list_head *lsthead = &psw->wake_task_list, *lnk;
418 struct wake_task_node *tncur; 418 struct wake_task_node *tncur;
419 struct wake_task_node tnode; 419 struct wake_task_node tnode;
diff --git a/fs/exec.c b/fs/exec.c
index c8494f513eaf..8344ba73a2a6 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -22,7 +22,6 @@
22 * formats. 22 * formats.
23 */ 23 */
24 24
25#include <linux/config.h>
26#include <linux/slab.h> 25#include <linux/slab.h>
27#include <linux/file.h> 26#include <linux/file.h>
28#include <linux/mman.h> 27#include <linux/mman.h>
diff --git a/fs/ext2/balloc.c b/fs/ext2/balloc.c
index 433a213a8bd9..d4870432ecfc 100644
--- a/fs/ext2/balloc.c
+++ b/fs/ext2/balloc.c
@@ -11,7 +11,6 @@
11 * David S. Miller (davem@caip.rutgers.edu), 1995 11 * David S. Miller (davem@caip.rutgers.edu), 1995
12 */ 12 */
13 13
14#include <linux/config.h>
15#include "ext2.h" 14#include "ext2.h"
16#include <linux/quotaops.h> 15#include <linux/quotaops.h>
17#include <linux/sched.h> 16#include <linux/sched.h>
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index 9f74a62be555..e65a019fc7a5 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -162,9 +162,9 @@ extern const struct file_operations ext2_file_operations;
162extern const struct file_operations ext2_xip_file_operations; 162extern const struct file_operations ext2_xip_file_operations;
163 163
164/* inode.c */ 164/* inode.c */
165extern struct address_space_operations ext2_aops; 165extern const struct address_space_operations ext2_aops;
166extern struct address_space_operations ext2_aops_xip; 166extern const struct address_space_operations ext2_aops_xip;
167extern struct address_space_operations ext2_nobh_aops; 167extern const struct address_space_operations ext2_nobh_aops;
168 168
169/* namei.c */ 169/* namei.c */
170extern struct inode_operations ext2_dir_inode_operations; 170extern struct inode_operations ext2_dir_inode_operations;
diff --git a/fs/ext2/ialloc.c b/fs/ext2/ialloc.c
index 308c252568c6..de85c61c58c5 100644
--- a/fs/ext2/ialloc.c
+++ b/fs/ext2/ialloc.c
@@ -12,7 +12,6 @@
12 * David S. Miller (davem@caip.rutgers.edu), 1995 12 * David S. Miller (davem@caip.rutgers.edu), 1995
13 */ 13 */
14 14
15#include <linux/config.h>
16#include <linux/quotaops.h> 15#include <linux/quotaops.h>
17#include <linux/sched.h> 16#include <linux/sched.h>
18#include <linux/backing-dev.h> 17#include <linux/backing-dev.h>
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 04af9c45dce2..fb4d3220eb8d 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -684,7 +684,7 @@ ext2_writepages(struct address_space *mapping, struct writeback_control *wbc)
684 return mpage_writepages(mapping, wbc, ext2_get_block); 684 return mpage_writepages(mapping, wbc, ext2_get_block);
685} 685}
686 686
687struct address_space_operations ext2_aops = { 687const struct address_space_operations ext2_aops = {
688 .readpage = ext2_readpage, 688 .readpage = ext2_readpage,
689 .readpages = ext2_readpages, 689 .readpages = ext2_readpages,
690 .writepage = ext2_writepage, 690 .writepage = ext2_writepage,
@@ -697,12 +697,12 @@ struct address_space_operations ext2_aops = {
697 .migratepage = buffer_migrate_page, 697 .migratepage = buffer_migrate_page,
698}; 698};
699 699
700struct address_space_operations ext2_aops_xip = { 700const struct address_space_operations ext2_aops_xip = {
701 .bmap = ext2_bmap, 701 .bmap = ext2_bmap,
702 .get_xip_page = ext2_get_xip_page, 702 .get_xip_page = ext2_get_xip_page,
703}; 703};
704 704
705struct address_space_operations ext2_nobh_aops = { 705const struct address_space_operations ext2_nobh_aops = {
706 .readpage = ext2_readpage, 706 .readpage = ext2_readpage,
707 .readpages = ext2_readpages, 707 .readpages = ext2_readpages,
708 .writepage = ext2_nobh_writepage, 708 .writepage = ext2_nobh_writepage,
diff --git a/fs/ext2/super.c b/fs/ext2/super.c
index d4233b2e6436..f2702cda9779 100644
--- a/fs/ext2/super.c
+++ b/fs/ext2/super.c
@@ -16,7 +16,6 @@
16 * David S. Miller (davem@caip.rutgers.edu), 1995 16 * David S. Miller (davem@caip.rutgers.edu), 1995
17 */ 17 */
18 18
19#include <linux/config.h>
20#include <linux/module.h> 19#include <linux/module.h>
21#include <linux/string.h> 20#include <linux/string.h>
22#include <linux/fs.h> 21#include <linux/fs.h>
@@ -1158,7 +1157,7 @@ static ssize_t ext2_quota_write(struct super_block *sb, int type,
1158 struct buffer_head tmp_bh; 1157 struct buffer_head tmp_bh;
1159 struct buffer_head *bh; 1158 struct buffer_head *bh;
1160 1159
1161 mutex_lock(&inode->i_mutex); 1160 mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA);
1162 while (towrite > 0) { 1161 while (towrite > 0) {
1163 tocopy = sb->s_blocksize - offset < towrite ? 1162 tocopy = sb->s_blocksize - offset < towrite ?
1164 sb->s_blocksize - offset : towrite; 1163 sb->s_blocksize - offset : towrite;
diff --git a/fs/ext2/xattr.h b/fs/ext2/xattr.h
index 67cfeb66e897..bf8175b2ced9 100644
--- a/fs/ext2/xattr.h
+++ b/fs/ext2/xattr.h
@@ -6,7 +6,6 @@
6 (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org> 6 (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
7*/ 7*/
8 8
9#include <linux/config.h>
10#include <linux/init.h> 9#include <linux/init.h>
11#include <linux/xattr.h> 10#include <linux/xattr.h>
12 11
diff --git a/fs/ext3/acl.h b/fs/ext3/acl.h
index 92d50b53a933..0d1e6279cbfd 100644
--- a/fs/ext3/acl.h
+++ b/fs/ext3/acl.h
@@ -62,9 +62,6 @@ extern int ext3_permission (struct inode *, int, struct nameidata *);
62extern int ext3_acl_chmod (struct inode *); 62extern int ext3_acl_chmod (struct inode *);
63extern int ext3_init_acl (handle_t *, struct inode *, struct inode *); 63extern int ext3_init_acl (handle_t *, struct inode *, struct inode *);
64 64
65extern int init_ext3_acl(void);
66extern void exit_ext3_acl(void);
67
68#else /* CONFIG_EXT3_FS_POSIX_ACL */ 65#else /* CONFIG_EXT3_FS_POSIX_ACL */
69#include <linux/sched.h> 66#include <linux/sched.h>
70#define ext3_permission NULL 67#define ext3_permission NULL
diff --git a/fs/ext3/balloc.c b/fs/ext3/balloc.c
index 96172e89ddc3..a504a40d6d29 100644
--- a/fs/ext3/balloc.c
+++ b/fs/ext3/balloc.c
@@ -11,7 +11,6 @@
11 * David S. Miller (davem@caip.rutgers.edu), 1995 11 * David S. Miller (davem@caip.rutgers.edu), 1995
12 */ 12 */
13 13
14#include <linux/config.h>
15#include <linux/time.h> 14#include <linux/time.h>
16#include <linux/capability.h> 15#include <linux/capability.h>
17#include <linux/fs.h> 16#include <linux/fs.h>
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index 0321e1b9034a..f804d5e9d60c 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -1698,7 +1698,7 @@ static int ext3_journalled_set_page_dirty(struct page *page)
1698 return __set_page_dirty_nobuffers(page); 1698 return __set_page_dirty_nobuffers(page);
1699} 1699}
1700 1700
1701static struct address_space_operations ext3_ordered_aops = { 1701static const struct address_space_operations ext3_ordered_aops = {
1702 .readpage = ext3_readpage, 1702 .readpage = ext3_readpage,
1703 .readpages = ext3_readpages, 1703 .readpages = ext3_readpages,
1704 .writepage = ext3_ordered_writepage, 1704 .writepage = ext3_ordered_writepage,
@@ -1712,7 +1712,7 @@ static struct address_space_operations ext3_ordered_aops = {
1712 .migratepage = buffer_migrate_page, 1712 .migratepage = buffer_migrate_page,
1713}; 1713};
1714 1714
1715static struct address_space_operations ext3_writeback_aops = { 1715static const struct address_space_operations ext3_writeback_aops = {
1716 .readpage = ext3_readpage, 1716 .readpage = ext3_readpage,
1717 .readpages = ext3_readpages, 1717 .readpages = ext3_readpages,
1718 .writepage = ext3_writeback_writepage, 1718 .writepage = ext3_writeback_writepage,
@@ -1726,7 +1726,7 @@ static struct address_space_operations ext3_writeback_aops = {
1726 .migratepage = buffer_migrate_page, 1726 .migratepage = buffer_migrate_page,
1727}; 1727};
1728 1728
1729static struct address_space_operations ext3_journalled_aops = { 1729static const struct address_space_operations ext3_journalled_aops = {
1730 .readpage = ext3_readpage, 1730 .readpage = ext3_readpage,
1731 .readpages = ext3_readpages, 1731 .readpages = ext3_readpages,
1732 .writepage = ext3_journalled_writepage, 1732 .writepage = ext3_journalled_writepage,
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c
index dfd811895d8f..5e1337fd878a 100644
--- a/fs/ext3/resize.c
+++ b/fs/ext3/resize.c
@@ -8,7 +8,6 @@
8 * This could probably be made into a module, because it is not often in use. 8 * This could probably be made into a module, because it is not often in use.
9 */ 9 */
10 10
11#include <linux/config.h>
12 11
13#define EXT3FS_DEBUG 12#define EXT3FS_DEBUG
14 13
diff --git a/fs/ext3/super.c b/fs/ext3/super.c
index b7483360a2db..813d589cc6c0 100644
--- a/fs/ext3/super.c
+++ b/fs/ext3/super.c
@@ -16,7 +16,6 @@
16 * David S. Miller (davem@caip.rutgers.edu), 1995 16 * David S. Miller (davem@caip.rutgers.edu), 1995
17 */ 17 */
18 18
19#include <linux/config.h>
20#include <linux/module.h> 19#include <linux/module.h>
21#include <linux/string.h> 20#include <linux/string.h>
22#include <linux/fs.h> 21#include <linux/fs.h>
@@ -2615,7 +2614,7 @@ static ssize_t ext3_quota_write(struct super_block *sb, int type,
2615 struct buffer_head *bh; 2614 struct buffer_head *bh;
2616 handle_t *handle = journal_current_handle(); 2615 handle_t *handle = journal_current_handle();
2617 2616
2618 mutex_lock(&inode->i_mutex); 2617 mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA);
2619 while (towrite > 0) { 2618 while (towrite > 0) {
2620 tocopy = sb->s_blocksize - offset < towrite ? 2619 tocopy = sb->s_blocksize - offset < towrite ?
2621 sb->s_blocksize - offset : towrite; 2620 sb->s_blocksize - offset : towrite;
diff --git a/fs/ext3/xattr.h b/fs/ext3/xattr.h
index 2ceae38f3d49..6b1ae1c6182c 100644
--- a/fs/ext3/xattr.h
+++ b/fs/ext3/xattr.h
@@ -6,7 +6,6 @@
6 (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org> 6 (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
7*/ 7*/
8 8
9#include <linux/config.h>
10#include <linux/xattr.h> 9#include <linux/xattr.h>
11 10
12/* Magic value in attribute blocks */ 11/* Magic value in attribute blocks */
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 7c35d582ec10..31b7174176ba 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -196,7 +196,7 @@ static sector_t _fat_bmap(struct address_space *mapping, sector_t block)
196 return generic_block_bmap(mapping, block, fat_get_block); 196 return generic_block_bmap(mapping, block, fat_get_block);
197} 197}
198 198
199static struct address_space_operations fat_aops = { 199static const struct address_space_operations fat_aops = {
200 .readpage = fat_readpage, 200 .readpage = fat_readpage,
201 .readpages = fat_readpages, 201 .readpages = fat_readpages,
202 .writepage = fat_writepage, 202 .writepage = fat_writepage,
diff --git a/fs/file.c b/fs/file.c
index 55f4e7022563..b3c6b82e6a9d 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -240,13 +240,9 @@ static struct fdtable *alloc_fdtable(int nr)
240 if (!fdt) 240 if (!fdt)
241 goto out; 241 goto out;
242 242
243 nfds = 8 * L1_CACHE_BYTES; 243 nfds = max_t(int, 8 * L1_CACHE_BYTES, roundup_pow_of_two(nr + 1));
244 /* Expand to the max in easy steps */ 244 if (nfds > NR_OPEN)
245 while (nfds <= nr) { 245 nfds = NR_OPEN;
246 nfds = nfds * 2;
247 if (nfds > NR_OPEN)
248 nfds = NR_OPEN;
249 }
250 246
251 new_openset = alloc_fdset(nfds); 247 new_openset = alloc_fdset(nfds);
252 new_execset = alloc_fdset(nfds); 248 new_execset = alloc_fdset(nfds);
@@ -277,11 +273,13 @@ static struct fdtable *alloc_fdtable(int nr)
277 } while (nfds <= nr); 273 } while (nfds <= nr);
278 new_fds = alloc_fd_array(nfds); 274 new_fds = alloc_fd_array(nfds);
279 if (!new_fds) 275 if (!new_fds)
280 goto out; 276 goto out2;
281 fdt->fd = new_fds; 277 fdt->fd = new_fds;
282 fdt->max_fds = nfds; 278 fdt->max_fds = nfds;
283 fdt->free_files = NULL; 279 fdt->free_files = NULL;
284 return fdt; 280 return fdt;
281out2:
282 nfds = fdt->max_fdset;
285out: 283out:
286 if (new_openset) 284 if (new_openset)
287 free_fdset(new_openset, nfds); 285 free_fdset(new_openset, nfds);
diff --git a/fs/file_table.c b/fs/file_table.c
index 506d5307108d..0131ba06e1ee 100644
--- a/fs/file_table.c
+++ b/fs/file_table.c
@@ -5,7 +5,6 @@
5 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) 5 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
6 */ 6 */
7 7
8#include <linux/config.h>
9#include <linux/string.h> 8#include <linux/string.h>
10#include <linux/slab.h> 9#include <linux/slab.h>
11#include <linux/file.h> 10#include <linux/file.h>
diff --git a/fs/freevxfs/vxfs_immed.c b/fs/freevxfs/vxfs_immed.c
index 6f5df1700e95..4e25f3fbed86 100644
--- a/fs/freevxfs/vxfs_immed.c
+++ b/fs/freevxfs/vxfs_immed.c
@@ -56,7 +56,7 @@ struct inode_operations vxfs_immed_symlink_iops = {
56/* 56/*
57 * Adress space operations for immed files and directories. 57 * Adress space operations for immed files and directories.
58 */ 58 */
59struct address_space_operations vxfs_immed_aops = { 59const struct address_space_operations vxfs_immed_aops = {
60 .readpage = vxfs_immed_readpage, 60 .readpage = vxfs_immed_readpage,
61}; 61};
62 62
diff --git a/fs/freevxfs/vxfs_inode.c b/fs/freevxfs/vxfs_inode.c
index f544aae9169f..ca6a39714771 100644
--- a/fs/freevxfs/vxfs_inode.c
+++ b/fs/freevxfs/vxfs_inode.c
@@ -41,8 +41,8 @@
41#include "vxfs_extern.h" 41#include "vxfs_extern.h"
42 42
43 43
44extern struct address_space_operations vxfs_aops; 44extern const struct address_space_operations vxfs_aops;
45extern struct address_space_operations vxfs_immed_aops; 45extern const struct address_space_operations vxfs_immed_aops;
46 46
47extern struct inode_operations vxfs_immed_symlink_iops; 47extern struct inode_operations vxfs_immed_symlink_iops;
48 48
@@ -295,7 +295,7 @@ vxfs_read_inode(struct inode *ip)
295{ 295{
296 struct super_block *sbp = ip->i_sb; 296 struct super_block *sbp = ip->i_sb;
297 struct vxfs_inode_info *vip; 297 struct vxfs_inode_info *vip;
298 struct address_space_operations *aops; 298 const struct address_space_operations *aops;
299 ino_t ino = ip->i_ino; 299 ino_t ino = ip->i_ino;
300 300
301 if (!(vip = __vxfs_iget(ino, VXFS_SBI(sbp)->vsi_ilist))) 301 if (!(vip = __vxfs_iget(ino, VXFS_SBI(sbp)->vsi_ilist)))
diff --git a/fs/freevxfs/vxfs_subr.c b/fs/freevxfs/vxfs_subr.c
index c1be118fc067..decac62efe57 100644
--- a/fs/freevxfs/vxfs_subr.c
+++ b/fs/freevxfs/vxfs_subr.c
@@ -42,7 +42,7 @@
42static int vxfs_readpage(struct file *, struct page *); 42static int vxfs_readpage(struct file *, struct page *);
43static sector_t vxfs_bmap(struct address_space *, sector_t); 43static sector_t vxfs_bmap(struct address_space *, sector_t);
44 44
45struct address_space_operations vxfs_aops = { 45const struct address_space_operations vxfs_aops = {
46 .readpage = vxfs_readpage, 46 .readpage = vxfs_readpage,
47 .bmap = vxfs_bmap, 47 .bmap = vxfs_bmap,
48 .sync_page = block_sync_page, 48 .sync_page = block_sync_page,
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 031b27a4bc9a..892643dc9af1 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -464,8 +464,8 @@ void sync_inodes_sb(struct super_block *sb, int wait)
464 .range_start = 0, 464 .range_start = 0,
465 .range_end = LLONG_MAX, 465 .range_end = LLONG_MAX,
466 }; 466 };
467 unsigned long nr_dirty = read_page_state(nr_dirty); 467 unsigned long nr_dirty = global_page_state(NR_FILE_DIRTY);
468 unsigned long nr_unstable = read_page_state(nr_unstable); 468 unsigned long nr_unstable = global_page_state(NR_UNSTABLE_NFS);
469 469
470 wbc.nr_to_write = nr_dirty + nr_unstable + 470 wbc.nr_to_write = nr_dirty + nr_unstable +
471 (inodes_stat.nr_inodes - inodes_stat.nr_unused) + 471 (inodes_stat.nr_inodes - inodes_stat.nr_unused) +
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 28aa81eae2cc..63614ed16336 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -770,7 +770,7 @@ static const struct file_operations fuse_direct_io_file_operations = {
770 /* no mmap and sendfile */ 770 /* no mmap and sendfile */
771}; 771};
772 772
773static struct address_space_operations fuse_file_aops = { 773static const struct address_space_operations fuse_file_aops = {
774 .readpage = fuse_readpage, 774 .readpage = fuse_readpage,
775 .prepare_write = fuse_prepare_write, 775 .prepare_write = fuse_prepare_write,
776 .commit_write = fuse_commit_write, 776 .commit_write = fuse_commit_write,
diff --git a/fs/hfs/hfs_fs.h b/fs/hfs/hfs_fs.h
index 3ed8663a8db1..735332dfd1b8 100644
--- a/fs/hfs/hfs_fs.h
+++ b/fs/hfs/hfs_fs.h
@@ -182,8 +182,8 @@ extern void hfs_file_truncate(struct inode *);
182extern int hfs_get_block(struct inode *, sector_t, struct buffer_head *, int); 182extern int hfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
183 183
184/* inode.c */ 184/* inode.c */
185extern struct address_space_operations hfs_aops; 185extern const struct address_space_operations hfs_aops;
186extern struct address_space_operations hfs_btree_aops; 186extern const struct address_space_operations hfs_btree_aops;
187 187
188extern struct inode *hfs_new_inode(struct inode *, struct qstr *, int); 188extern struct inode *hfs_new_inode(struct inode *, struct qstr *, int);
189extern void hfs_inode_write_fork(struct inode *, struct hfs_extent *, __be32 *, __be32 *); 189extern void hfs_inode_write_fork(struct inode *, struct hfs_extent *, __be32 *, __be32 *);
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
index 2d4ced22201b..315cf44a90b2 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -114,7 +114,7 @@ static int hfs_writepages(struct address_space *mapping,
114 return mpage_writepages(mapping, wbc, hfs_get_block); 114 return mpage_writepages(mapping, wbc, hfs_get_block);
115} 115}
116 116
117struct address_space_operations hfs_btree_aops = { 117const struct address_space_operations hfs_btree_aops = {
118 .readpage = hfs_readpage, 118 .readpage = hfs_readpage,
119 .writepage = hfs_writepage, 119 .writepage = hfs_writepage,
120 .sync_page = block_sync_page, 120 .sync_page = block_sync_page,
@@ -124,7 +124,7 @@ struct address_space_operations hfs_btree_aops = {
124 .releasepage = hfs_releasepage, 124 .releasepage = hfs_releasepage,
125}; 125};
126 126
127struct address_space_operations hfs_aops = { 127const struct address_space_operations hfs_aops = {
128 .readpage = hfs_readpage, 128 .readpage = hfs_readpage,
129 .writepage = hfs_writepage, 129 .writepage = hfs_writepage,
130 .sync_page = block_sync_page, 130 .sync_page = block_sync_page,
diff --git a/fs/hfs/super.c b/fs/hfs/super.c
index d9227bf14e86..34937ee83ab1 100644
--- a/fs/hfs/super.c
+++ b/fs/hfs/super.c
@@ -12,7 +12,6 @@
12 * Based on the minix file system code, (C) 1991, 1992 by Linus Torvalds 12 * Based on the minix file system code, (C) 1991, 1992 by Linus Torvalds
13 */ 13 */
14 14
15#include <linux/config.h>
16#include <linux/module.h> 15#include <linux/module.h>
17#include <linux/blkdev.h> 16#include <linux/blkdev.h>
18#include <linux/mount.h> 17#include <linux/mount.h>
diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h
index 7ae393637a0c..8a1ca5ef7ada 100644
--- a/fs/hfsplus/hfsplus_fs.h
+++ b/fs/hfsplus/hfsplus_fs.h
@@ -323,8 +323,8 @@ int hfsplus_file_extend(struct inode *);
323void hfsplus_file_truncate(struct inode *); 323void hfsplus_file_truncate(struct inode *);
324 324
325/* inode.c */ 325/* inode.c */
326extern struct address_space_operations hfsplus_aops; 326extern const struct address_space_operations hfsplus_aops;
327extern struct address_space_operations hfsplus_btree_aops; 327extern const struct address_space_operations hfsplus_btree_aops;
328 328
329void hfsplus_inode_read_fork(struct inode *, struct hfsplus_fork_raw *); 329void hfsplus_inode_read_fork(struct inode *, struct hfsplus_fork_raw *);
330void hfsplus_inode_write_fork(struct inode *, struct hfsplus_fork_raw *); 330void hfsplus_inode_write_fork(struct inode *, struct hfsplus_fork_raw *);
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index acf66dba3e01..924ecdef8091 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -109,7 +109,7 @@ static int hfsplus_writepages(struct address_space *mapping,
109 return mpage_writepages(mapping, wbc, hfsplus_get_block); 109 return mpage_writepages(mapping, wbc, hfsplus_get_block);
110} 110}
111 111
112struct address_space_operations hfsplus_btree_aops = { 112const struct address_space_operations hfsplus_btree_aops = {
113 .readpage = hfsplus_readpage, 113 .readpage = hfsplus_readpage,
114 .writepage = hfsplus_writepage, 114 .writepage = hfsplus_writepage,
115 .sync_page = block_sync_page, 115 .sync_page = block_sync_page,
@@ -119,7 +119,7 @@ struct address_space_operations hfsplus_btree_aops = {
119 .releasepage = hfsplus_releasepage, 119 .releasepage = hfsplus_releasepage,
120}; 120};
121 121
122struct address_space_operations hfsplus_aops = { 122const struct address_space_operations hfsplus_aops = {
123 .readpage = hfsplus_readpage, 123 .readpage = hfsplus_readpage,
124 .writepage = hfsplus_writepage, 124 .writepage = hfsplus_writepage,
125 .sync_page = block_sync_page, 125 .sync_page = block_sync_page,
diff --git a/fs/hfsplus/super.c b/fs/hfsplus/super.c
index 0a92fa2336a2..d279d5924f28 100644
--- a/fs/hfsplus/super.c
+++ b/fs/hfsplus/super.c
@@ -7,7 +7,6 @@
7 * 7 *
8 */ 8 */
9 9
10#include <linux/config.h>
11#include <linux/module.h> 10#include <linux/module.h>
12#include <linux/init.h> 11#include <linux/init.h>
13#include <linux/pagemap.h> 12#include <linux/pagemap.h>
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index 8e0d37743e7c..b82e3d9c8790 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -54,7 +54,7 @@ static int append = 0;
54 54
55static struct inode_operations hostfs_iops; 55static struct inode_operations hostfs_iops;
56static struct inode_operations hostfs_dir_iops; 56static struct inode_operations hostfs_dir_iops;
57static struct address_space_operations hostfs_link_aops; 57static const struct address_space_operations hostfs_link_aops;
58 58
59#ifndef MODULE 59#ifndef MODULE
60static int __init hostfs_args(char *options, int *add) 60static int __init hostfs_args(char *options, int *add)
@@ -518,7 +518,7 @@ int hostfs_commit_write(struct file *file, struct page *page, unsigned from,
518 return(err); 518 return(err);
519} 519}
520 520
521static struct address_space_operations hostfs_aops = { 521static const struct address_space_operations hostfs_aops = {
522 .writepage = hostfs_writepage, 522 .writepage = hostfs_writepage,
523 .readpage = hostfs_readpage, 523 .readpage = hostfs_readpage,
524 .set_page_dirty = __set_page_dirty_nobuffers, 524 .set_page_dirty = __set_page_dirty_nobuffers,
@@ -935,7 +935,7 @@ int hostfs_link_readpage(struct file *file, struct page *page)
935 return(err); 935 return(err);
936} 936}
937 937
938static struct address_space_operations hostfs_link_aops = { 938static const struct address_space_operations hostfs_link_aops = {
939 .readpage = hostfs_link_readpage, 939 .readpage = hostfs_link_readpage,
940}; 940};
941 941
diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c
index d3b9fffe45a1..d9eb19b7b8ae 100644
--- a/fs/hpfs/file.c
+++ b/fs/hpfs/file.c
@@ -99,7 +99,7 @@ static sector_t _hpfs_bmap(struct address_space *mapping, sector_t block)
99{ 99{
100 return generic_block_bmap(mapping,block,hpfs_get_block); 100 return generic_block_bmap(mapping,block,hpfs_get_block);
101} 101}
102struct address_space_operations hpfs_aops = { 102const struct address_space_operations hpfs_aops = {
103 .readpage = hpfs_readpage, 103 .readpage = hpfs_readpage,
104 .writepage = hpfs_writepage, 104 .writepage = hpfs_writepage,
105 .sync_page = block_sync_page, 105 .sync_page = block_sync_page,
diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h
index 29b7a3e55173..f687d54ed442 100644
--- a/fs/hpfs/hpfs_fn.h
+++ b/fs/hpfs/hpfs_fn.h
@@ -268,7 +268,7 @@ void hpfs_set_ea(struct inode *, struct fnode *, char *, char *, int);
268int hpfs_file_fsync(struct file *, struct dentry *, int); 268int hpfs_file_fsync(struct file *, struct dentry *, int);
269extern const struct file_operations hpfs_file_ops; 269extern const struct file_operations hpfs_file_ops;
270extern struct inode_operations hpfs_file_iops; 270extern struct inode_operations hpfs_file_iops;
271extern struct address_space_operations hpfs_aops; 271extern const struct address_space_operations hpfs_aops;
272 272
273/* inode.c */ 273/* inode.c */
274 274
@@ -304,7 +304,7 @@ void hpfs_decide_conv(struct inode *, unsigned char *, unsigned);
304/* namei.c */ 304/* namei.c */
305 305
306extern struct inode_operations hpfs_dir_iops; 306extern struct inode_operations hpfs_dir_iops;
307extern struct address_space_operations hpfs_symlink_aops; 307extern const struct address_space_operations hpfs_symlink_aops;
308 308
309static inline struct hpfs_inode_info *hpfs_i(struct inode *inode) 309static inline struct hpfs_inode_info *hpfs_i(struct inode *inode)
310{ 310{
diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c
index a03abb12c610..59e7dc182a0c 100644
--- a/fs/hpfs/namei.c
+++ b/fs/hpfs/namei.c
@@ -538,7 +538,7 @@ fail:
538 return err; 538 return err;
539} 539}
540 540
541struct address_space_operations hpfs_symlink_aops = { 541const struct address_space_operations hpfs_symlink_aops = {
542 .readpage = hpfs_symlink_readpage 542 .readpage = hpfs_symlink_readpage
543}; 543};
544 544
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index e6410d8edd0e..c3920c96dadf 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -34,7 +34,7 @@
34#define HUGETLBFS_MAGIC 0x958458f6 34#define HUGETLBFS_MAGIC 0x958458f6
35 35
36static struct super_operations hugetlbfs_ops; 36static struct super_operations hugetlbfs_ops;
37static struct address_space_operations hugetlbfs_aops; 37static const struct address_space_operations hugetlbfs_aops;
38const struct file_operations hugetlbfs_file_operations; 38const struct file_operations hugetlbfs_file_operations;
39static struct inode_operations hugetlbfs_dir_inode_operations; 39static struct inode_operations hugetlbfs_dir_inode_operations;
40static struct inode_operations hugetlbfs_inode_operations; 40static struct inode_operations hugetlbfs_inode_operations;
@@ -83,8 +83,6 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
83 83
84 ret = -ENOMEM; 84 ret = -ENOMEM;
85 len = vma_len + ((loff_t)vma->vm_pgoff << PAGE_SHIFT); 85 len = vma_len + ((loff_t)vma->vm_pgoff << PAGE_SHIFT);
86 if (!(vma->vm_flags & VM_WRITE) && len > inode->i_size)
87 goto out;
88 86
89 if (vma->vm_flags & VM_MAYSHARE && 87 if (vma->vm_flags & VM_MAYSHARE &&
90 hugetlb_reserve_pages(inode, vma->vm_pgoff >> (HPAGE_SHIFT-PAGE_SHIFT), 88 hugetlb_reserve_pages(inode, vma->vm_pgoff >> (HPAGE_SHIFT-PAGE_SHIFT),
@@ -93,7 +91,7 @@ static int hugetlbfs_file_mmap(struct file *file, struct vm_area_struct *vma)
93 91
94 ret = 0; 92 ret = 0;
95 hugetlb_prefault_arch_hook(vma->vm_mm); 93 hugetlb_prefault_arch_hook(vma->vm_mm);
96 if (inode->i_size < len) 94 if (vma->vm_flags & VM_WRITE && inode->i_size < len)
97 inode->i_size = len; 95 inode->i_size = len;
98out: 96out:
99 mutex_unlock(&inode->i_mutex); 97 mutex_unlock(&inode->i_mutex);
@@ -547,7 +545,7 @@ static void hugetlbfs_destroy_inode(struct inode *inode)
547 kmem_cache_free(hugetlbfs_inode_cachep, HUGETLBFS_I(inode)); 545 kmem_cache_free(hugetlbfs_inode_cachep, HUGETLBFS_I(inode));
548} 546}
549 547
550static struct address_space_operations hugetlbfs_aops = { 548static const struct address_space_operations hugetlbfs_aops = {
551 .readpage = hugetlbfs_readpage, 549 .readpage = hugetlbfs_readpage,
552 .prepare_write = hugetlbfs_prepare_write, 550 .prepare_write = hugetlbfs_prepare_write,
553 .commit_write = hugetlbfs_commit_write, 551 .commit_write = hugetlbfs_commit_write,
diff --git a/fs/inode.c b/fs/inode.c
index 3a2446a27d2c..0bf9f0444a96 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -4,7 +4,6 @@
4 * (C) 1997 Linus Torvalds 4 * (C) 1997 Linus Torvalds
5 */ 5 */
6 6
7#include <linux/config.h>
8#include <linux/fs.h> 7#include <linux/fs.h>
9#include <linux/mm.h> 8#include <linux/mm.h>
10#include <linux/dcache.h> 9#include <linux/dcache.h>
@@ -102,7 +101,7 @@ static kmem_cache_t * inode_cachep __read_mostly;
102 101
103static struct inode *alloc_inode(struct super_block *sb) 102static struct inode *alloc_inode(struct super_block *sb)
104{ 103{
105 static struct address_space_operations empty_aops; 104 static const struct address_space_operations empty_aops;
106 static struct inode_operations empty_iops; 105 static struct inode_operations empty_iops;
107 static const struct file_operations empty_fops; 106 static const struct file_operations empty_fops;
108 struct inode *inode; 107 struct inode *inode;
@@ -452,15 +451,14 @@ static void prune_icache(int nr_to_scan)
452 nr_pruned++; 451 nr_pruned++;
453 } 452 }
454 inodes_stat.nr_unused -= nr_pruned; 453 inodes_stat.nr_unused -= nr_pruned;
454 if (current_is_kswapd())
455 __count_vm_events(KSWAPD_INODESTEAL, reap);
456 else
457 __count_vm_events(PGINODESTEAL, reap);
455 spin_unlock(&inode_lock); 458 spin_unlock(&inode_lock);
456 459
457 dispose_list(&freeable); 460 dispose_list(&freeable);
458 mutex_unlock(&iprune_mutex); 461 mutex_unlock(&iprune_mutex);
459
460 if (current_is_kswapd())
461 mod_page_state(kswapd_inodesteal, reap);
462 else
463 mod_page_state(pginodesteal, reap);
464} 462}
465 463
466/* 464/*
diff --git a/fs/ioctl.c b/fs/ioctl.c
index f8aeec3ca10c..4b7660b09ac0 100644
--- a/fs/ioctl.c
+++ b/fs/ioctl.c
@@ -4,7 +4,6 @@
4 * Copyright (C) 1991, 1992 Linus Torvalds 4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */ 5 */
6 6
7#include <linux/config.h>
8#include <linux/syscalls.h> 7#include <linux/syscalls.h>
9#include <linux/mm.h> 8#include <linux/mm.h>
10#include <linux/smp_lock.h> 9#include <linux/smp_lock.h>
diff --git a/fs/ioprio.c b/fs/ioprio.c
index 7fa76ed53c10..93aa5715f224 100644
--- a/fs/ioprio.c
+++ b/fs/ioprio.c
@@ -125,11 +125,24 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio)
125 return ret; 125 return ret;
126} 126}
127 127
128static int get_task_ioprio(struct task_struct *p)
129{
130 int ret;
131
132 ret = security_task_getioprio(p);
133 if (ret)
134 goto out;
135 ret = p->ioprio;
136out:
137 return ret;
138}
139
128asmlinkage long sys_ioprio_get(int which, int who) 140asmlinkage long sys_ioprio_get(int which, int who)
129{ 141{
130 struct task_struct *g, *p; 142 struct task_struct *g, *p;
131 struct user_struct *user; 143 struct user_struct *user;
132 int ret = -ESRCH; 144 int ret = -ESRCH;
145 int tmpio;
133 146
134 read_lock_irq(&tasklist_lock); 147 read_lock_irq(&tasklist_lock);
135 switch (which) { 148 switch (which) {
@@ -139,16 +152,19 @@ asmlinkage long sys_ioprio_get(int which, int who)
139 else 152 else
140 p = find_task_by_pid(who); 153 p = find_task_by_pid(who);
141 if (p) 154 if (p)
142 ret = p->ioprio; 155 ret = get_task_ioprio(p);
143 break; 156 break;
144 case IOPRIO_WHO_PGRP: 157 case IOPRIO_WHO_PGRP:
145 if (!who) 158 if (!who)
146 who = process_group(current); 159 who = process_group(current);
147 do_each_task_pid(who, PIDTYPE_PGID, p) { 160 do_each_task_pid(who, PIDTYPE_PGID, p) {
161 tmpio = get_task_ioprio(p);
162 if (tmpio < 0)
163 continue;
148 if (ret == -ESRCH) 164 if (ret == -ESRCH)
149 ret = p->ioprio; 165 ret = tmpio;
150 else 166 else
151 ret = ioprio_best(ret, p->ioprio); 167 ret = ioprio_best(ret, tmpio);
152 } while_each_task_pid(who, PIDTYPE_PGID, p); 168 } while_each_task_pid(who, PIDTYPE_PGID, p);
153 break; 169 break;
154 case IOPRIO_WHO_USER: 170 case IOPRIO_WHO_USER:
@@ -163,10 +179,13 @@ asmlinkage long sys_ioprio_get(int which, int who)
163 do_each_thread(g, p) { 179 do_each_thread(g, p) {
164 if (p->uid != user->uid) 180 if (p->uid != user->uid)
165 continue; 181 continue;
182 tmpio = get_task_ioprio(p);
183 if (tmpio < 0)
184 continue;
166 if (ret == -ESRCH) 185 if (ret == -ESRCH)
167 ret = p->ioprio; 186 ret = tmpio;
168 else 187 else
169 ret = ioprio_best(ret, p->ioprio); 188 ret = ioprio_best(ret, tmpio);
170 } while_each_thread(g, p); 189 } while_each_thread(g, p);
171 190
172 if (who) 191 if (who)
diff --git a/fs/isofs/compress.c b/fs/isofs/compress.c
index 4917315db732..731816332b12 100644
--- a/fs/isofs/compress.c
+++ b/fs/isofs/compress.c
@@ -16,7 +16,6 @@
16 * Transparent decompression of files on an iso9660 filesystem 16 * Transparent decompression of files on an iso9660 filesystem
17 */ 17 */
18 18
19#include <linux/config.h>
20#include <linux/module.h> 19#include <linux/module.h>
21#include <linux/init.h> 20#include <linux/init.h>
22 21
@@ -312,7 +311,7 @@ eio:
312 return err; 311 return err;
313} 312}
314 313
315struct address_space_operations zisofs_aops = { 314const struct address_space_operations zisofs_aops = {
316 .readpage = zisofs_readpage, 315 .readpage = zisofs_readpage,
317 /* No sync_page operation supported? */ 316 /* No sync_page operation supported? */
318 /* No bmap operation supported */ 317 /* No bmap operation supported */
diff --git a/fs/isofs/dir.c b/fs/isofs/dir.c
index 5440ea292c69..27e276987fd2 100644
--- a/fs/isofs/dir.c
+++ b/fs/isofs/dir.c
@@ -10,7 +10,6 @@
10 * 10 *
11 * isofs directory handling functions 11 * isofs directory handling functions
12 */ 12 */
13#include <linux/config.h>
14#include <linux/smp_lock.h> 13#include <linux/smp_lock.h>
15#include "isofs.h" 14#include "isofs.h"
16 15
diff --git a/fs/isofs/inode.c b/fs/isofs/inode.c
index 3f9c8ba1fa1f..14391361c886 100644
--- a/fs/isofs/inode.c
+++ b/fs/isofs/inode.c
@@ -11,7 +11,6 @@
11 * 2004 Paul Serice - NFS Export Operations 11 * 2004 Paul Serice - NFS Export Operations
12 */ 12 */
13 13
14#include <linux/config.h>
15#include <linux/init.h> 14#include <linux/init.h>
16#include <linux/module.h> 15#include <linux/module.h>
17 16
@@ -1054,7 +1053,7 @@ static sector_t _isofs_bmap(struct address_space *mapping, sector_t block)
1054 return generic_block_bmap(mapping,block,isofs_get_block); 1053 return generic_block_bmap(mapping,block,isofs_get_block);
1055} 1054}
1056 1055
1057static struct address_space_operations isofs_aops = { 1056static const struct address_space_operations isofs_aops = {
1058 .readpage = isofs_readpage, 1057 .readpage = isofs_readpage,
1059 .sync_page = block_sync_page, 1058 .sync_page = block_sync_page,
1060 .bmap = _isofs_bmap 1059 .bmap = _isofs_bmap
diff --git a/fs/isofs/isofs.h b/fs/isofs/isofs.h
index b87ba066f5e7..e6308c8b5735 100644
--- a/fs/isofs/isofs.h
+++ b/fs/isofs/isofs.h
@@ -176,5 +176,5 @@ isofs_normalize_block_and_offset(struct iso_directory_record* de,
176 176
177extern struct inode_operations isofs_dir_inode_operations; 177extern struct inode_operations isofs_dir_inode_operations;
178extern const struct file_operations isofs_dir_operations; 178extern const struct file_operations isofs_dir_operations;
179extern struct address_space_operations isofs_symlink_aops; 179extern const struct address_space_operations isofs_symlink_aops;
180extern struct export_operations isofs_export_ops; 180extern struct export_operations isofs_export_ops;
diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c
index 4326cb47f8fa..f3a1db3098de 100644
--- a/fs/isofs/rock.c
+++ b/fs/isofs/rock.c
@@ -754,6 +754,6 @@ error:
754 return -EIO; 754 return -EIO;
755} 755}
756 756
757struct address_space_operations isofs_symlink_aops = { 757const struct address_space_operations isofs_symlink_aops = {
758 .readpage = rock_ridge_symlink_readpage 758 .readpage = rock_ridge_symlink_readpage
759}; 759};
diff --git a/fs/isofs/zisofs.h b/fs/isofs/zisofs.h
index d78485d101c2..273795709155 100644
--- a/fs/isofs/zisofs.h
+++ b/fs/isofs/zisofs.h
@@ -15,7 +15,7 @@
15 */ 15 */
16 16
17#ifdef CONFIG_ZISOFS 17#ifdef CONFIG_ZISOFS
18extern struct address_space_operations zisofs_aops; 18extern const struct address_space_operations zisofs_aops;
19extern int __init zisofs_init(void); 19extern int __init zisofs_init(void);
20extern void zisofs_cleanup(void); 20extern void zisofs_cleanup(void);
21#endif 21#endif
diff --git a/fs/jffs/inode-v23.c b/fs/jffs/inode-v23.c
index 9e46ea6da752..93068697a9bf 100644
--- a/fs/jffs/inode-v23.c
+++ b/fs/jffs/inode-v23.c
@@ -59,7 +59,7 @@ static const struct file_operations jffs_file_operations;
59static struct inode_operations jffs_file_inode_operations; 59static struct inode_operations jffs_file_inode_operations;
60static const struct file_operations jffs_dir_operations; 60static const struct file_operations jffs_dir_operations;
61static struct inode_operations jffs_dir_inode_operations; 61static struct inode_operations jffs_dir_inode_operations;
62static struct address_space_operations jffs_address_operations; 62static const struct address_space_operations jffs_address_operations;
63 63
64kmem_cache_t *node_cache = NULL; 64kmem_cache_t *node_cache = NULL;
65kmem_cache_t *fm_cache = NULL; 65kmem_cache_t *fm_cache = NULL;
@@ -1614,7 +1614,7 @@ jffs_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
1614} /* jffs_ioctl() */ 1614} /* jffs_ioctl() */
1615 1615
1616 1616
1617static struct address_space_operations jffs_address_operations = { 1617static const struct address_space_operations jffs_address_operations = {
1618 .readpage = jffs_readpage, 1618 .readpage = jffs_readpage,
1619 .prepare_write = jffs_prepare_write, 1619 .prepare_write = jffs_prepare_write,
1620 .commit_write = jffs_commit_write, 1620 .commit_write = jffs_commit_write,
diff --git a/fs/jffs/intrep.c b/fs/jffs/intrep.c
index 5371a403130a..9000f1effedf 100644
--- a/fs/jffs/intrep.c
+++ b/fs/jffs/intrep.c
@@ -55,7 +55,6 @@
55 * 55 *
56 */ 56 */
57 57
58#include <linux/config.h>
59#include <linux/types.h> 58#include <linux/types.h>
60#include <linux/slab.h> 59#include <linux/slab.h>
61#include <linux/jffs.h> 60#include <linux/jffs.h>
diff --git a/fs/jffs/jffs_fm.h b/fs/jffs/jffs_fm.h
index c794d923df2a..9ee6ad29eff5 100644
--- a/fs/jffs/jffs_fm.h
+++ b/fs/jffs/jffs_fm.h
@@ -20,7 +20,6 @@
20#ifndef __LINUX_JFFS_FM_H__ 20#ifndef __LINUX_JFFS_FM_H__
21#define __LINUX_JFFS_FM_H__ 21#define __LINUX_JFFS_FM_H__
22 22
23#include <linux/config.h>
24#include <linux/types.h> 23#include <linux/types.h>
25#include <linux/jffs.h> 24#include <linux/jffs.h>
26#include <linux/mtd/mtd.h> 25#include <linux/mtd/mtd.h>
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c
index 320dd48b834e..0ae3cd10702c 100644
--- a/fs/jffs2/acl.c
+++ b/fs/jffs2/acl.c
@@ -267,6 +267,8 @@ static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
267 } 267 }
268 268
269 rc = do_jffs2_setxattr(inode, xprefix, "", value, size, 0); 269 rc = do_jffs2_setxattr(inode, xprefix, "", value, size, 0);
270 if (!value && rc == -ENODATA)
271 rc = 0;
270 if (value) 272 if (value)
271 kfree(value); 273 kfree(value);
272 if (!rc) { 274 if (!rc) {
@@ -343,10 +345,8 @@ int jffs2_init_acl(struct inode *inode, struct inode *dir)
343 return rc; 345 return rc;
344} 346}
345 347
346void jffs2_clear_acl(struct inode *inode) 348void jffs2_clear_acl(struct jffs2_inode_info *f)
347{ 349{
348 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
349
350 if (f->i_acl_access && f->i_acl_access != JFFS2_ACL_NOT_CACHED) { 350 if (f->i_acl_access && f->i_acl_access != JFFS2_ACL_NOT_CACHED) {
351 posix_acl_release(f->i_acl_access); 351 posix_acl_release(f->i_acl_access);
352 f->i_acl_access = JFFS2_ACL_NOT_CACHED; 352 f->i_acl_access = JFFS2_ACL_NOT_CACHED;
diff --git a/fs/jffs2/acl.h b/fs/jffs2/acl.h
index 8893bd1a6ba7..fa327dbd3171 100644
--- a/fs/jffs2/acl.h
+++ b/fs/jffs2/acl.h
@@ -30,7 +30,7 @@ struct jffs2_acl_header {
30extern int jffs2_permission(struct inode *, int, struct nameidata *); 30extern int jffs2_permission(struct inode *, int, struct nameidata *);
31extern int jffs2_acl_chmod(struct inode *); 31extern int jffs2_acl_chmod(struct inode *);
32extern int jffs2_init_acl(struct inode *, struct inode *); 32extern int jffs2_init_acl(struct inode *, struct inode *);
33extern void jffs2_clear_acl(struct inode *); 33extern void jffs2_clear_acl(struct jffs2_inode_info *);
34 34
35extern struct xattr_handler jffs2_acl_access_xattr_handler; 35extern struct xattr_handler jffs2_acl_access_xattr_handler;
36extern struct xattr_handler jffs2_acl_default_xattr_handler; 36extern struct xattr_handler jffs2_acl_default_xattr_handler;
@@ -40,6 +40,6 @@ extern struct xattr_handler jffs2_acl_default_xattr_handler;
40#define jffs2_permission NULL 40#define jffs2_permission NULL
41#define jffs2_acl_chmod(inode) (0) 41#define jffs2_acl_chmod(inode) (0)
42#define jffs2_init_acl(inode,dir) (0) 42#define jffs2_init_acl(inode,dir) (0)
43#define jffs2_clear_acl(inode) 43#define jffs2_clear_acl(f)
44 44
45#endif /* CONFIG_JFFS2_FS_POSIX_ACL */ 45#endif /* CONFIG_JFFS2_FS_POSIX_ACL */
diff --git a/fs/jffs2/compr_zlib.c b/fs/jffs2/compr_zlib.c
index 5c63e0cdcf4c..3681d0728ac7 100644
--- a/fs/jffs2/compr_zlib.c
+++ b/fs/jffs2/compr_zlib.c
@@ -15,7 +15,6 @@
15#error "The userspace support got too messy and was removed. Update your mkfs.jffs2" 15#error "The userspace support got too messy and was removed. Update your mkfs.jffs2"
16#endif 16#endif
17 17
18#include <linux/config.h>
19#include <linux/kernel.h> 18#include <linux/kernel.h>
20#include <linux/sched.h> 19#include <linux/sched.h>
21#include <linux/slab.h> 20#include <linux/slab.h>
diff --git a/fs/jffs2/debug.h b/fs/jffs2/debug.h
index 5fa494a792b2..3daf3bca0376 100644
--- a/fs/jffs2/debug.h
+++ b/fs/jffs2/debug.h
@@ -13,7 +13,6 @@
13#ifndef _JFFS2_DEBUG_H_ 13#ifndef _JFFS2_DEBUG_H_
14#define _JFFS2_DEBUG_H_ 14#define _JFFS2_DEBUG_H_
15 15
16#include <linux/config.h>
17 16
18#ifndef CONFIG_JFFS2_FS_DEBUG 17#ifndef CONFIG_JFFS2_FS_DEBUG
19#define CONFIG_JFFS2_FS_DEBUG 0 18#define CONFIG_JFFS2_FS_DEBUG 0
diff --git a/fs/jffs2/erase.c b/fs/jffs2/erase.c
index b8886f048eaa..ad0121088dde 100644
--- a/fs/jffs2/erase.c
+++ b/fs/jffs2/erase.c
@@ -225,7 +225,6 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c,
225 at the end of the linked list. Stash it and continue 225 at the end of the linked list. Stash it and continue
226 from the beginning of the list */ 226 from the beginning of the list */
227 ic = (struct jffs2_inode_cache *)(*prev); 227 ic = (struct jffs2_inode_cache *)(*prev);
228 BUG_ON(ic->class != RAWNODE_CLASS_INODE_CACHE);
229 prev = &ic->nodes; 228 prev = &ic->nodes;
230 continue; 229 continue;
231 } 230 }
@@ -249,7 +248,8 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c,
249 248
250 /* PARANOIA */ 249 /* PARANOIA */
251 if (!ic) { 250 if (!ic) {
252 printk(KERN_WARNING "inode_cache not found in remove_node_refs()!!\n"); 251 JFFS2_WARNING("inode_cache/xattr_datum/xattr_ref"
252 " not found in remove_node_refs()!!\n");
253 return; 253 return;
254 } 254 }
255 255
@@ -274,8 +274,19 @@ static inline void jffs2_remove_node_refs_from_ino_list(struct jffs2_sb_info *c,
274 printk("\n"); 274 printk("\n");
275 }); 275 });
276 276
277 if (ic->nodes == (void *)ic && ic->nlink == 0) 277 switch (ic->class) {
278 jffs2_del_ino_cache(c, ic); 278#ifdef CONFIG_JFFS2_FS_XATTR
279 case RAWNODE_CLASS_XATTR_DATUM:
280 jffs2_release_xattr_datum(c, (struct jffs2_xattr_datum *)ic);
281 break;
282 case RAWNODE_CLASS_XATTR_REF:
283 jffs2_release_xattr_ref(c, (struct jffs2_xattr_ref *)ic);
284 break;
285#endif
286 default:
287 if (ic->nodes == (void *)ic && ic->nlink == 0)
288 jffs2_del_ino_cache(c, ic);
289 }
279} 290}
280 291
281void jffs2_free_jeb_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb) 292void jffs2_free_jeb_node_refs(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb)
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index bb8844f40e48..3ed6e3e120b6 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -62,7 +62,7 @@ struct inode_operations jffs2_file_inode_operations =
62 .removexattr = jffs2_removexattr 62 .removexattr = jffs2_removexattr
63}; 63};
64 64
65struct address_space_operations jffs2_file_address_operations = 65const struct address_space_operations jffs2_file_address_operations =
66{ 66{
67 .readpage = jffs2_readpage, 67 .readpage = jffs2_readpage,
68 .prepare_write =jffs2_prepare_write, 68 .prepare_write =jffs2_prepare_write,
diff --git a/fs/jffs2/fs.c b/fs/jffs2/fs.c
index 2900ec3ec3af..4780f82825d6 100644
--- a/fs/jffs2/fs.c
+++ b/fs/jffs2/fs.c
@@ -12,7 +12,6 @@
12 */ 12 */
13 13
14#include <linux/capability.h> 14#include <linux/capability.h>
15#include <linux/config.h>
16#include <linux/kernel.h> 15#include <linux/kernel.h>
17#include <linux/sched.h> 16#include <linux/sched.h>
18#include <linux/fs.h> 17#include <linux/fs.h>
@@ -227,8 +226,6 @@ void jffs2_clear_inode (struct inode *inode)
227 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); 226 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
228 227
229 D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode)); 228 D1(printk(KERN_DEBUG "jffs2_clear_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode));
230
231 jffs2_xattr_delete_inode(c, f->inocache);
232 jffs2_do_clear_inode(c, f); 229 jffs2_do_clear_inode(c, f);
233} 230}
234 231
diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c
index 477c526d638b..daff3341ff92 100644
--- a/fs/jffs2/gc.c
+++ b/fs/jffs2/gc.c
@@ -165,6 +165,7 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
165 D1(printk(KERN_DEBUG "Skipping check of ino #%d with nlink zero\n", 165 D1(printk(KERN_DEBUG "Skipping check of ino #%d with nlink zero\n",
166 ic->ino)); 166 ic->ino));
167 spin_unlock(&c->inocache_lock); 167 spin_unlock(&c->inocache_lock);
168 jffs2_xattr_delete_inode(c, ic);
168 continue; 169 continue;
169 } 170 }
170 switch(ic->state) { 171 switch(ic->state) {
@@ -275,13 +276,12 @@ int jffs2_garbage_collect_pass(struct jffs2_sb_info *c)
275 * We can decide whether this node is inode or xattr by ic->class. */ 276 * We can decide whether this node is inode or xattr by ic->class. */
276 if (ic->class == RAWNODE_CLASS_XATTR_DATUM 277 if (ic->class == RAWNODE_CLASS_XATTR_DATUM
277 || ic->class == RAWNODE_CLASS_XATTR_REF) { 278 || ic->class == RAWNODE_CLASS_XATTR_REF) {
278 BUG_ON(raw->next_in_ino != (void *)ic);
279 spin_unlock(&c->erase_completion_lock); 279 spin_unlock(&c->erase_completion_lock);
280 280
281 if (ic->class == RAWNODE_CLASS_XATTR_DATUM) { 281 if (ic->class == RAWNODE_CLASS_XATTR_DATUM) {
282 ret = jffs2_garbage_collect_xattr_datum(c, (struct jffs2_xattr_datum *)ic); 282 ret = jffs2_garbage_collect_xattr_datum(c, (struct jffs2_xattr_datum *)ic, raw);
283 } else { 283 } else {
284 ret = jffs2_garbage_collect_xattr_ref(c, (struct jffs2_xattr_ref *)ic); 284 ret = jffs2_garbage_collect_xattr_ref(c, (struct jffs2_xattr_ref *)ic, raw);
285 } 285 }
286 goto release_sem; 286 goto release_sem;
287 } 287 }
diff --git a/fs/jffs2/jffs2_fs_sb.h b/fs/jffs2/jffs2_fs_sb.h
index 935fec1b1201..b98594992eed 100644
--- a/fs/jffs2/jffs2_fs_sb.h
+++ b/fs/jffs2/jffs2_fs_sb.h
@@ -119,8 +119,11 @@ struct jffs2_sb_info {
119#ifdef CONFIG_JFFS2_FS_XATTR 119#ifdef CONFIG_JFFS2_FS_XATTR
120#define XATTRINDEX_HASHSIZE (57) 120#define XATTRINDEX_HASHSIZE (57)
121 uint32_t highest_xid; 121 uint32_t highest_xid;
122 uint32_t highest_xseqno;
122 struct list_head xattrindex[XATTRINDEX_HASHSIZE]; 123 struct list_head xattrindex[XATTRINDEX_HASHSIZE];
123 struct list_head xattr_unchecked; 124 struct list_head xattr_unchecked;
125 struct list_head xattr_dead_list;
126 struct jffs2_xattr_ref *xref_dead_list;
124 struct jffs2_xattr_ref *xref_temp; 127 struct jffs2_xattr_ref *xref_temp;
125 struct rw_semaphore xattr_sem; 128 struct rw_semaphore xattr_sem;
126 uint32_t xdatum_mem_usage; 129 uint32_t xdatum_mem_usage;
diff --git a/fs/jffs2/malloc.c b/fs/jffs2/malloc.c
index 4889d0700c0e..33f291005012 100644
--- a/fs/jffs2/malloc.c
+++ b/fs/jffs2/malloc.c
@@ -190,7 +190,7 @@ void jffs2_free_tmp_dnode_info(struct jffs2_tmp_dnode_info *x)
190 kmem_cache_free(tmp_dnode_info_slab, x); 190 kmem_cache_free(tmp_dnode_info_slab, x);
191} 191}
192 192
193struct jffs2_raw_node_ref *jffs2_alloc_refblock(void) 193static struct jffs2_raw_node_ref *jffs2_alloc_refblock(void)
194{ 194{
195 struct jffs2_raw_node_ref *ret; 195 struct jffs2_raw_node_ref *ret;
196 196
@@ -291,6 +291,7 @@ struct jffs2_xattr_datum *jffs2_alloc_xattr_datum(void)
291 291
292 memset(xd, 0, sizeof(struct jffs2_xattr_datum)); 292 memset(xd, 0, sizeof(struct jffs2_xattr_datum));
293 xd->class = RAWNODE_CLASS_XATTR_DATUM; 293 xd->class = RAWNODE_CLASS_XATTR_DATUM;
294 xd->node = (void *)xd;
294 INIT_LIST_HEAD(&xd->xindex); 295 INIT_LIST_HEAD(&xd->xindex);
295 return xd; 296 return xd;
296} 297}
@@ -309,6 +310,7 @@ struct jffs2_xattr_ref *jffs2_alloc_xattr_ref(void)
309 310
310 memset(ref, 0, sizeof(struct jffs2_xattr_ref)); 311 memset(ref, 0, sizeof(struct jffs2_xattr_ref));
311 ref->class = RAWNODE_CLASS_XATTR_REF; 312 ref->class = RAWNODE_CLASS_XATTR_REF;
313 ref->node = (void *)ref;
312 return ref; 314 return ref;
313} 315}
314 316
diff --git a/fs/jffs2/nodelist.c b/fs/jffs2/nodelist.c
index 927dfe42ba76..7675b33396c7 100644
--- a/fs/jffs2/nodelist.c
+++ b/fs/jffs2/nodelist.c
@@ -906,6 +906,9 @@ void jffs2_del_ino_cache(struct jffs2_sb_info *c, struct jffs2_inode_cache *old)
906{ 906{
907 struct jffs2_inode_cache **prev; 907 struct jffs2_inode_cache **prev;
908 908
909#ifdef CONFIG_JFFS2_FS_XATTR
910 BUG_ON(old->xref);
911#endif
909 dbg_inocache("del %p (ino #%u)\n", old, old->ino); 912 dbg_inocache("del %p (ino #%u)\n", old, old->ino);
910 spin_lock(&c->inocache_lock); 913 spin_lock(&c->inocache_lock);
911 914
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h
index b16c60bbcf6e..cae92c14116d 100644
--- a/fs/jffs2/nodelist.h
+++ b/fs/jffs2/nodelist.h
@@ -14,7 +14,6 @@
14#ifndef __JFFS2_NODELIST_H__ 14#ifndef __JFFS2_NODELIST_H__
15#define __JFFS2_NODELIST_H__ 15#define __JFFS2_NODELIST_H__
16 16
17#include <linux/config.h>
18#include <linux/fs.h> 17#include <linux/fs.h>
19#include <linux/types.h> 18#include <linux/types.h>
20#include <linux/jffs2.h> 19#include <linux/jffs2.h>
@@ -427,8 +426,6 @@ char *jffs2_getlink(struct jffs2_sb_info *c, struct jffs2_inode_info *f);
427/* scan.c */ 426/* scan.c */
428int jffs2_scan_medium(struct jffs2_sb_info *c); 427int jffs2_scan_medium(struct jffs2_sb_info *c);
429void jffs2_rotate_lists(struct jffs2_sb_info *c); 428void jffs2_rotate_lists(struct jffs2_sb_info *c);
430int jffs2_fill_scan_buf(struct jffs2_sb_info *c, void *buf,
431 uint32_t ofs, uint32_t len);
432struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino); 429struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uint32_t ino);
433int jffs2_scan_classify_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb); 430int jffs2_scan_classify_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb);
434int jffs2_scan_dirty_space(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t size); 431int jffs2_scan_dirty_space(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, uint32_t size);
diff --git a/fs/jffs2/nodemgmt.c b/fs/jffs2/nodemgmt.c
index ac0c350ed7d7..d88376992ed9 100644
--- a/fs/jffs2/nodemgmt.c
+++ b/fs/jffs2/nodemgmt.c
@@ -683,19 +683,26 @@ void jffs2_mark_node_obsolete(struct jffs2_sb_info *c, struct jffs2_raw_node_ref
683 spin_lock(&c->erase_completion_lock); 683 spin_lock(&c->erase_completion_lock);
684 684
685 ic = jffs2_raw_ref_to_ic(ref); 685 ic = jffs2_raw_ref_to_ic(ref);
686 /* It seems we should never call jffs2_mark_node_obsolete() for
687 XATTR nodes.... yet. Make sure we notice if/when we change
688 that :) */
689 BUG_ON(ic->class != RAWNODE_CLASS_INODE_CACHE);
690 for (p = &ic->nodes; (*p) != ref; p = &((*p)->next_in_ino)) 686 for (p = &ic->nodes; (*p) != ref; p = &((*p)->next_in_ino))
691 ; 687 ;
692 688
693 *p = ref->next_in_ino; 689 *p = ref->next_in_ino;
694 ref->next_in_ino = NULL; 690 ref->next_in_ino = NULL;
695 691
696 if (ic->nodes == (void *)ic && ic->nlink == 0) 692 switch (ic->class) {
697 jffs2_del_ino_cache(c, ic); 693#ifdef CONFIG_JFFS2_FS_XATTR
698 694 case RAWNODE_CLASS_XATTR_DATUM:
695 jffs2_release_xattr_datum(c, (struct jffs2_xattr_datum *)ic);
696 break;
697 case RAWNODE_CLASS_XATTR_REF:
698 jffs2_release_xattr_ref(c, (struct jffs2_xattr_ref *)ic);
699 break;
700#endif
701 default:
702 if (ic->nodes == (void *)ic && ic->nlink == 0)
703 jffs2_del_ino_cache(c, ic);
704 break;
705 }
699 spin_unlock(&c->erase_completion_lock); 706 spin_unlock(&c->erase_completion_lock);
700 } 707 }
701 708
diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
index 6b5223565405..9f41fc01a371 100644
--- a/fs/jffs2/os-linux.h
+++ b/fs/jffs2/os-linux.h
@@ -158,7 +158,7 @@ extern struct inode_operations jffs2_dir_inode_operations;
158/* file.c */ 158/* file.c */
159extern const struct file_operations jffs2_file_operations; 159extern const struct file_operations jffs2_file_operations;
160extern struct inode_operations jffs2_file_inode_operations; 160extern struct inode_operations jffs2_file_inode_operations;
161extern struct address_space_operations jffs2_file_address_operations; 161extern const struct address_space_operations jffs2_file_address_operations;
162int jffs2_fsync(struct file *, struct dentry *, int); 162int jffs2_fsync(struct file *, struct dentry *, int);
163int jffs2_do_readpage_unlock (struct inode *inode, struct page *pg); 163int jffs2_do_readpage_unlock (struct inode *inode, struct page *pg);
164 164
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index 5fec012b02ed..266423b2709d 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -968,6 +968,8 @@ void jffs2_do_clear_inode(struct jffs2_sb_info *c, struct jffs2_inode_info *f)
968 struct jffs2_full_dirent *fd, *fds; 968 struct jffs2_full_dirent *fd, *fds;
969 int deleted; 969 int deleted;
970 970
971 jffs2_clear_acl(f);
972 jffs2_xattr_delete_inode(c, f->inocache);
971 down(&f->sem); 973 down(&f->sem);
972 deleted = f->inocache && !f->inocache->nlink; 974 deleted = f->inocache && !f->inocache->nlink;
973 975
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c
index 61618080b86f..e2413466ddd5 100644
--- a/fs/jffs2/scan.c
+++ b/fs/jffs2/scan.c
@@ -274,8 +274,8 @@ int jffs2_scan_medium(struct jffs2_sb_info *c)
274 return ret; 274 return ret;
275} 275}
276 276
277int jffs2_fill_scan_buf (struct jffs2_sb_info *c, void *buf, 277static int jffs2_fill_scan_buf(struct jffs2_sb_info *c, void *buf,
278 uint32_t ofs, uint32_t len) 278 uint32_t ofs, uint32_t len)
279{ 279{
280 int ret; 280 int ret;
281 size_t retlen; 281 size_t retlen;
@@ -317,20 +317,23 @@ static int jffs2_scan_xattr_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
317 struct jffs2_summary *s) 317 struct jffs2_summary *s)
318{ 318{
319 struct jffs2_xattr_datum *xd; 319 struct jffs2_xattr_datum *xd;
320 uint32_t totlen, crc; 320 uint32_t xid, version, totlen, crc;
321 int err; 321 int err;
322 322
323 crc = crc32(0, rx, sizeof(struct jffs2_raw_xattr) - 4); 323 crc = crc32(0, rx, sizeof(struct jffs2_raw_xattr) - 4);
324 if (crc != je32_to_cpu(rx->node_crc)) { 324 if (crc != je32_to_cpu(rx->node_crc)) {
325 if (je32_to_cpu(rx->node_crc) != 0xffffffff) 325 JFFS2_WARNING("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
326 JFFS2_WARNING("node CRC failed at %#08x, read=%#08x, calc=%#08x\n", 326 ofs, je32_to_cpu(rx->node_crc), crc);
327 ofs, je32_to_cpu(rx->node_crc), crc);
328 if ((err = jffs2_scan_dirty_space(c, jeb, je32_to_cpu(rx->totlen)))) 327 if ((err = jffs2_scan_dirty_space(c, jeb, je32_to_cpu(rx->totlen))))
329 return err; 328 return err;
330 return 0; 329 return 0;
331 } 330 }
332 331
333 totlen = PAD(sizeof(*rx) + rx->name_len + 1 + je16_to_cpu(rx->value_len)); 332 xid = je32_to_cpu(rx->xid);
333 version = je32_to_cpu(rx->version);
334
335 totlen = PAD(sizeof(struct jffs2_raw_xattr)
336 + rx->name_len + 1 + je16_to_cpu(rx->value_len));
334 if (totlen != je32_to_cpu(rx->totlen)) { 337 if (totlen != je32_to_cpu(rx->totlen)) {
335 JFFS2_WARNING("node length mismatch at %#08x, read=%u, calc=%u\n", 338 JFFS2_WARNING("node length mismatch at %#08x, read=%u, calc=%u\n",
336 ofs, je32_to_cpu(rx->totlen), totlen); 339 ofs, je32_to_cpu(rx->totlen), totlen);
@@ -339,22 +342,24 @@ static int jffs2_scan_xattr_node(struct jffs2_sb_info *c, struct jffs2_erasebloc
339 return 0; 342 return 0;
340 } 343 }
341 344
342 xd = jffs2_setup_xattr_datum(c, je32_to_cpu(rx->xid), je32_to_cpu(rx->version)); 345 xd = jffs2_setup_xattr_datum(c, xid, version);
343 if (IS_ERR(xd)) { 346 if (IS_ERR(xd))
344 if (PTR_ERR(xd) == -EEXIST) {
345 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(rx->totlen)))))
346 return err;
347 return 0;
348 }
349 return PTR_ERR(xd); 347 return PTR_ERR(xd);
350 }
351 xd->xprefix = rx->xprefix;
352 xd->name_len = rx->name_len;
353 xd->value_len = je16_to_cpu(rx->value_len);
354 xd->data_crc = je32_to_cpu(rx->data_crc);
355 348
356 xd->node = jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, totlen, NULL); 349 if (xd->version > version) {
357 /* FIXME */ xd->node->next_in_ino = (void *)xd; 350 struct jffs2_raw_node_ref *raw
351 = jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, totlen, NULL);
352 raw->next_in_ino = xd->node->next_in_ino;
353 xd->node->next_in_ino = raw;
354 } else {
355 xd->version = version;
356 xd->xprefix = rx->xprefix;
357 xd->name_len = rx->name_len;
358 xd->value_len = je16_to_cpu(rx->value_len);
359 xd->data_crc = je32_to_cpu(rx->data_crc);
360
361 jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, totlen, (void *)xd);
362 }
358 363
359 if (jffs2_sum_active()) 364 if (jffs2_sum_active())
360 jffs2_sum_add_xattr_mem(s, rx, ofs - jeb->offset); 365 jffs2_sum_add_xattr_mem(s, rx, ofs - jeb->offset);
@@ -373,9 +378,8 @@ static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock
373 378
374 crc = crc32(0, rr, sizeof(*rr) - 4); 379 crc = crc32(0, rr, sizeof(*rr) - 4);
375 if (crc != je32_to_cpu(rr->node_crc)) { 380 if (crc != je32_to_cpu(rr->node_crc)) {
376 if (je32_to_cpu(rr->node_crc) != 0xffffffff) 381 JFFS2_WARNING("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
377 JFFS2_WARNING("node CRC failed at %#08x, read=%#08x, calc=%#08x\n", 382 ofs, je32_to_cpu(rr->node_crc), crc);
378 ofs, je32_to_cpu(rr->node_crc), crc);
379 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(rr->totlen))))) 383 if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(rr->totlen)))))
380 return err; 384 return err;
381 return 0; 385 return 0;
@@ -395,6 +399,7 @@ static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock
395 return -ENOMEM; 399 return -ENOMEM;
396 400
397 /* BEFORE jffs2_build_xattr_subsystem() called, 401 /* BEFORE jffs2_build_xattr_subsystem() called,
402 * and AFTER xattr_ref is marked as a dead xref,
398 * ref->xid is used to store 32bit xid, xd is not used 403 * ref->xid is used to store 32bit xid, xd is not used
399 * ref->ino is used to store 32bit inode-number, ic is not used 404 * ref->ino is used to store 32bit inode-number, ic is not used
400 * Thoes variables are declared as union, thus using those 405 * Thoes variables are declared as union, thus using those
@@ -404,11 +409,13 @@ static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock
404 */ 409 */
405 ref->ino = je32_to_cpu(rr->ino); 410 ref->ino = je32_to_cpu(rr->ino);
406 ref->xid = je32_to_cpu(rr->xid); 411 ref->xid = je32_to_cpu(rr->xid);
412 ref->xseqno = je32_to_cpu(rr->xseqno);
413 if (ref->xseqno > c->highest_xseqno)
414 c->highest_xseqno = (ref->xseqno & ~XREF_DELETE_MARKER);
407 ref->next = c->xref_temp; 415 ref->next = c->xref_temp;
408 c->xref_temp = ref; 416 c->xref_temp = ref;
409 417
410 ref->node = jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, PAD(je32_to_cpu(rr->totlen)), NULL); 418 jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, PAD(je32_to_cpu(rr->totlen)), (void *)ref);
411 /* FIXME */ ref->node->next_in_ino = (void *)ref;
412 419
413 if (jffs2_sum_active()) 420 if (jffs2_sum_active())
414 jffs2_sum_add_xref_mem(s, rr, ofs - jeb->offset); 421 jffs2_sum_add_xref_mem(s, rr, ofs - jeb->offset);
diff --git a/fs/jffs2/summary.c b/fs/jffs2/summary.c
index be1acc3dad97..c19bd476e8ec 100644
--- a/fs/jffs2/summary.c
+++ b/fs/jffs2/summary.c
@@ -5,7 +5,7 @@
5 * Zoltan Sogor <weth@inf.u-szeged.hu>, 5 * Zoltan Sogor <weth@inf.u-szeged.hu>,
6 * Patrik Kluba <pajko@halom.u-szeged.hu>, 6 * Patrik Kluba <pajko@halom.u-szeged.hu>,
7 * University of Szeged, Hungary 7 * University of Szeged, Hungary
8 * 2005 KaiGai Kohei <kaigai@ak.jp.nec.com> 8 * 2006 KaiGai Kohei <kaigai@ak.jp.nec.com>
9 * 9 *
10 * For licensing information, see the file 'LICENCE' in this directory. 10 * For licensing information, see the file 'LICENCE' in this directory.
11 * 11 *
@@ -310,8 +310,6 @@ int jffs2_sum_add_kvec(struct jffs2_sb_info *c, const struct kvec *invecs,
310#ifdef CONFIG_JFFS2_FS_XATTR 310#ifdef CONFIG_JFFS2_FS_XATTR
311 case JFFS2_NODETYPE_XATTR: { 311 case JFFS2_NODETYPE_XATTR: {
312 struct jffs2_sum_xattr_mem *temp; 312 struct jffs2_sum_xattr_mem *temp;
313 if (je32_to_cpu(node->x.version) == 0xffffffff)
314 return 0;
315 temp = kmalloc(sizeof(struct jffs2_sum_xattr_mem), GFP_KERNEL); 313 temp = kmalloc(sizeof(struct jffs2_sum_xattr_mem), GFP_KERNEL);
316 if (!temp) 314 if (!temp)
317 goto no_mem; 315 goto no_mem;
@@ -327,10 +325,6 @@ int jffs2_sum_add_kvec(struct jffs2_sb_info *c, const struct kvec *invecs,
327 } 325 }
328 case JFFS2_NODETYPE_XREF: { 326 case JFFS2_NODETYPE_XREF: {
329 struct jffs2_sum_xref_mem *temp; 327 struct jffs2_sum_xref_mem *temp;
330
331 if (je32_to_cpu(node->r.ino) == 0xffffffff
332 && je32_to_cpu(node->r.xid) == 0xffffffff)
333 return 0;
334 temp = kmalloc(sizeof(struct jffs2_sum_xref_mem), GFP_KERNEL); 328 temp = kmalloc(sizeof(struct jffs2_sum_xref_mem), GFP_KERNEL);
335 if (!temp) 329 if (!temp)
336 goto no_mem; 330 goto no_mem;
@@ -483,22 +477,20 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
483 477
484 xd = jffs2_setup_xattr_datum(c, je32_to_cpu(spx->xid), 478 xd = jffs2_setup_xattr_datum(c, je32_to_cpu(spx->xid),
485 je32_to_cpu(spx->version)); 479 je32_to_cpu(spx->version));
486 if (IS_ERR(xd)) { 480 if (IS_ERR(xd))
487 if (PTR_ERR(xd) == -EEXIST) {
488 /* a newer version of xd exists */
489 if ((err = jffs2_scan_dirty_space(c, jeb, je32_to_cpu(spx->totlen))))
490 return err;
491 sp += JFFS2_SUMMARY_XATTR_SIZE;
492 break;
493 }
494 JFFS2_NOTICE("allocation of xattr_datum failed\n");
495 return PTR_ERR(xd); 481 return PTR_ERR(xd);
482 if (xd->version > je32_to_cpu(spx->version)) {
483 /* node is not the newest one */
484 struct jffs2_raw_node_ref *raw
485 = sum_link_node_ref(c, jeb, je32_to_cpu(spx->offset) | REF_UNCHECKED,
486 PAD(je32_to_cpu(spx->totlen)), NULL);
487 raw->next_in_ino = xd->node->next_in_ino;
488 xd->node->next_in_ino = raw;
489 } else {
490 xd->version = je32_to_cpu(spx->version);
491 sum_link_node_ref(c, jeb, je32_to_cpu(spx->offset) | REF_UNCHECKED,
492 PAD(je32_to_cpu(spx->totlen)), (void *)xd);
496 } 493 }
497
498 xd->node = sum_link_node_ref(c, jeb, je32_to_cpu(spx->offset) | REF_UNCHECKED,
499 PAD(je32_to_cpu(spx->totlen)), NULL);
500 /* FIXME */ xd->node->next_in_ino = (void *)xd;
501
502 *pseudo_random += je32_to_cpu(spx->xid); 494 *pseudo_random += je32_to_cpu(spx->xid);
503 sp += JFFS2_SUMMARY_XATTR_SIZE; 495 sp += JFFS2_SUMMARY_XATTR_SIZE;
504 496
@@ -519,14 +511,11 @@ static int jffs2_sum_process_sum_data(struct jffs2_sb_info *c, struct jffs2_eras
519 JFFS2_NOTICE("allocation of xattr_datum failed\n"); 511 JFFS2_NOTICE("allocation of xattr_datum failed\n");
520 return -ENOMEM; 512 return -ENOMEM;
521 } 513 }
522 ref->ino = 0xfffffffe;
523 ref->xid = 0xfffffffd;
524 ref->next = c->xref_temp; 514 ref->next = c->xref_temp;
525 c->xref_temp = ref; 515 c->xref_temp = ref;
526 516
527 ref->node = sum_link_node_ref(c, jeb, je32_to_cpu(spr->offset) | REF_UNCHECKED, 517 sum_link_node_ref(c, jeb, je32_to_cpu(spr->offset) | REF_UNCHECKED,
528 PAD(sizeof(struct jffs2_raw_xref)), NULL); 518 PAD(sizeof(struct jffs2_raw_xref)), (void *)ref);
529 /* FIXME */ ref->node->next_in_ino = (void *)ref;
530 519
531 *pseudo_random += ref->node->flash_offset; 520 *pseudo_random += ref->node->flash_offset;
532 sp += JFFS2_SUMMARY_XREF_SIZE; 521 sp += JFFS2_SUMMARY_XREF_SIZE;
diff --git a/fs/jffs2/super.c b/fs/jffs2/super.c
index 2378a662c256..68e3953419b4 100644
--- a/fs/jffs2/super.c
+++ b/fs/jffs2/super.c
@@ -11,7 +11,6 @@
11 * 11 *
12 */ 12 */
13 13
14#include <linux/config.h>
15#include <linux/kernel.h> 14#include <linux/kernel.h>
16#include <linux/module.h> 15#include <linux/module.h>
17#include <linux/slab.h> 16#include <linux/slab.h>
diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c
index 2d82e250be34..25bc1ae08648 100644
--- a/fs/jffs2/xattr.c
+++ b/fs/jffs2/xattr.c
@@ -23,18 +23,15 @@
23 * xattr_datum_hashkey(xprefix, xname, xvalue, xsize) 23 * xattr_datum_hashkey(xprefix, xname, xvalue, xsize)
24 * is used to calcurate xdatum hashkey. The reminder of hashkey into XATTRINDEX_HASHSIZE is 24 * is used to calcurate xdatum hashkey. The reminder of hashkey into XATTRINDEX_HASHSIZE is
25 * the index of the xattr name/value pair cache (c->xattrindex). 25 * the index of the xattr name/value pair cache (c->xattrindex).
26 * is_xattr_datum_unchecked(c, xd)
27 * returns 1, if xdatum contains any unchecked raw nodes. if all raw nodes are not
28 * unchecked, it returns 0.
26 * unload_xattr_datum(c, xd) 29 * unload_xattr_datum(c, xd)
27 * is used to release xattr name/value pair and detach from c->xattrindex. 30 * is used to release xattr name/value pair and detach from c->xattrindex.
28 * reclaim_xattr_datum(c) 31 * reclaim_xattr_datum(c)
29 * is used to reclaim xattr name/value pairs on the xattr name/value pair cache when 32 * is used to reclaim xattr name/value pairs on the xattr name/value pair cache when
30 * memory usage by cache is over c->xdatum_mem_threshold. Currentry, this threshold 33 * memory usage by cache is over c->xdatum_mem_threshold. Currentry, this threshold
31 * is hard coded as 32KiB. 34 * is hard coded as 32KiB.
32 * delete_xattr_datum_node(c, xd)
33 * is used to delete a jffs2 node is dominated by xdatum. When EBS(Erase Block Summary) is
34 * enabled, it overwrites the obsolete node by myself.
35 * delete_xattr_datum(c, xd)
36 * is used to delete jffs2_xattr_datum object. It must be called with 0-value of reference
37 * counter. (It means how many jffs2_xattr_ref object refers this xdatum.)
38 * do_verify_xattr_datum(c, xd) 35 * do_verify_xattr_datum(c, xd)
39 * is used to load the xdatum informations without name/value pair from the medium. 36 * is used to load the xdatum informations without name/value pair from the medium.
40 * It's necessary once, because those informations are not collected during mounting 37 * It's necessary once, because those informations are not collected during mounting
@@ -53,8 +50,11 @@
53 * is used to write xdatum to medium. xd->version will be incremented. 50 * is used to write xdatum to medium. xd->version will be incremented.
54 * create_xattr_datum(c, xprefix, xname, xvalue, xsize) 51 * create_xattr_datum(c, xprefix, xname, xvalue, xsize)
55 * is used to create new xdatum and write to medium. 52 * is used to create new xdatum and write to medium.
53 * unrefer_xattr_datum(c, xd)
54 * is used to delete a xdatum. When nobody refers this xdatum, JFFS2_XFLAGS_DEAD
55 * is set on xd->flags and chained xattr_dead_list or release it immediately.
56 * In the first case, the garbage collector release it later.
56 * -------------------------------------------------- */ 57 * -------------------------------------------------- */
57
58static uint32_t xattr_datum_hashkey(int xprefix, const char *xname, const char *xvalue, int xsize) 58static uint32_t xattr_datum_hashkey(int xprefix, const char *xname, const char *xvalue, int xsize)
59{ 59{
60 int name_len = strlen(xname); 60 int name_len = strlen(xname);
@@ -62,6 +62,22 @@ static uint32_t xattr_datum_hashkey(int xprefix, const char *xname, const char *
62 return crc32(xprefix, xname, name_len) ^ crc32(xprefix, xvalue, xsize); 62 return crc32(xprefix, xname, name_len) ^ crc32(xprefix, xvalue, xsize);
63} 63}
64 64
65static int is_xattr_datum_unchecked(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
66{
67 struct jffs2_raw_node_ref *raw;
68 int rc = 0;
69
70 spin_lock(&c->erase_completion_lock);
71 for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) {
72 if (ref_flags(raw) == REF_UNCHECKED) {
73 rc = 1;
74 break;
75 }
76 }
77 spin_unlock(&c->erase_completion_lock);
78 return rc;
79}
80
65static void unload_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) 81static void unload_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
66{ 82{
67 /* must be called under down_write(xattr_sem) */ 83 /* must be called under down_write(xattr_sem) */
@@ -107,77 +123,33 @@ static void reclaim_xattr_datum(struct jffs2_sb_info *c)
107 before, c->xdatum_mem_usage, before - c->xdatum_mem_usage); 123 before, c->xdatum_mem_usage, before - c->xdatum_mem_usage);
108} 124}
109 125
110static void delete_xattr_datum_node(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
111{
112 /* must be called under down_write(xattr_sem) */
113 struct jffs2_raw_xattr rx;
114 size_t length;
115 int rc;
116
117 if (!xd->node) {
118 JFFS2_WARNING("xdatum (xid=%u) is removed twice.\n", xd->xid);
119 return;
120 }
121 if (jffs2_sum_active()) {
122 memset(&rx, 0xff, sizeof(struct jffs2_raw_xattr));
123 rc = jffs2_flash_read(c, ref_offset(xd->node),
124 sizeof(struct jffs2_unknown_node),
125 &length, (char *)&rx);
126 if (rc || length != sizeof(struct jffs2_unknown_node)) {
127 JFFS2_ERROR("jffs2_flash_read()=%d, req=%zu, read=%zu at %#08x\n",
128 rc, sizeof(struct jffs2_unknown_node),
129 length, ref_offset(xd->node));
130 }
131 rc = jffs2_flash_write(c, ref_offset(xd->node), sizeof(rx),
132 &length, (char *)&rx);
133 if (rc || length != sizeof(struct jffs2_raw_xattr)) {
134 JFFS2_ERROR("jffs2_flash_write()=%d, req=%zu, wrote=%zu ar %#08x\n",
135 rc, sizeof(rx), length, ref_offset(xd->node));
136 }
137 }
138 spin_lock(&c->erase_completion_lock);
139 xd->node->next_in_ino = NULL;
140 spin_unlock(&c->erase_completion_lock);
141 jffs2_mark_node_obsolete(c, xd->node);
142 xd->node = NULL;
143}
144
145static void delete_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
146{
147 /* must be called under down_write(xattr_sem) */
148 BUG_ON(xd->refcnt);
149
150 unload_xattr_datum(c, xd);
151 if (xd->node) {
152 delete_xattr_datum_node(c, xd);
153 xd->node = NULL;
154 }
155 jffs2_free_xattr_datum(xd);
156}
157
158static int do_verify_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) 126static int do_verify_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
159{ 127{
160 /* must be called under down_write(xattr_sem) */ 128 /* must be called under down_write(xattr_sem) */
161 struct jffs2_eraseblock *jeb; 129 struct jffs2_eraseblock *jeb;
130 struct jffs2_raw_node_ref *raw;
162 struct jffs2_raw_xattr rx; 131 struct jffs2_raw_xattr rx;
163 size_t readlen; 132 size_t readlen;
164 uint32_t crc, totlen; 133 uint32_t crc, offset, totlen;
165 int rc; 134 int rc;
166 135
167 BUG_ON(!xd->node); 136 spin_lock(&c->erase_completion_lock);
168 BUG_ON(ref_flags(xd->node) != REF_UNCHECKED); 137 offset = ref_offset(xd->node);
138 if (ref_flags(xd->node) == REF_PRISTINE)
139 goto complete;
140 spin_unlock(&c->erase_completion_lock);
169 141
170 rc = jffs2_flash_read(c, ref_offset(xd->node), sizeof(rx), &readlen, (char *)&rx); 142 rc = jffs2_flash_read(c, offset, sizeof(rx), &readlen, (char *)&rx);
171 if (rc || readlen != sizeof(rx)) { 143 if (rc || readlen != sizeof(rx)) {
172 JFFS2_WARNING("jffs2_flash_read()=%d, req=%zu, read=%zu at %#08x\n", 144 JFFS2_WARNING("jffs2_flash_read()=%d, req=%zu, read=%zu at %#08x\n",
173 rc, sizeof(rx), readlen, ref_offset(xd->node)); 145 rc, sizeof(rx), readlen, offset);
174 return rc ? rc : -EIO; 146 return rc ? rc : -EIO;
175 } 147 }
176 crc = crc32(0, &rx, sizeof(rx) - 4); 148 crc = crc32(0, &rx, sizeof(rx) - 4);
177 if (crc != je32_to_cpu(rx.node_crc)) { 149 if (crc != je32_to_cpu(rx.node_crc)) {
178 if (je32_to_cpu(rx.node_crc) != 0xffffffff) 150 JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
179 JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n", 151 offset, je32_to_cpu(rx.hdr_crc), crc);
180 ref_offset(xd->node), je32_to_cpu(rx.hdr_crc), crc); 152 xd->flags |= JFFS2_XFLAGS_INVALID;
181 return EIO; 153 return EIO;
182 } 154 }
183 totlen = PAD(sizeof(rx) + rx.name_len + 1 + je16_to_cpu(rx.value_len)); 155 totlen = PAD(sizeof(rx) + rx.name_len + 1 + je16_to_cpu(rx.value_len));
@@ -188,11 +160,12 @@ static int do_verify_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_dat
188 || je32_to_cpu(rx.version) != xd->version) { 160 || je32_to_cpu(rx.version) != xd->version) {
189 JFFS2_ERROR("inconsistent xdatum at %#08x, magic=%#04x/%#04x, " 161 JFFS2_ERROR("inconsistent xdatum at %#08x, magic=%#04x/%#04x, "
190 "nodetype=%#04x/%#04x, totlen=%u/%u, xid=%u/%u, version=%u/%u\n", 162 "nodetype=%#04x/%#04x, totlen=%u/%u, xid=%u/%u, version=%u/%u\n",
191 ref_offset(xd->node), je16_to_cpu(rx.magic), JFFS2_MAGIC_BITMASK, 163 offset, je16_to_cpu(rx.magic), JFFS2_MAGIC_BITMASK,
192 je16_to_cpu(rx.nodetype), JFFS2_NODETYPE_XATTR, 164 je16_to_cpu(rx.nodetype), JFFS2_NODETYPE_XATTR,
193 je32_to_cpu(rx.totlen), totlen, 165 je32_to_cpu(rx.totlen), totlen,
194 je32_to_cpu(rx.xid), xd->xid, 166 je32_to_cpu(rx.xid), xd->xid,
195 je32_to_cpu(rx.version), xd->version); 167 je32_to_cpu(rx.version), xd->version);
168 xd->flags |= JFFS2_XFLAGS_INVALID;
196 return EIO; 169 return EIO;
197 } 170 }
198 xd->xprefix = rx.xprefix; 171 xd->xprefix = rx.xprefix;
@@ -200,14 +173,17 @@ static int do_verify_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_dat
200 xd->value_len = je16_to_cpu(rx.value_len); 173 xd->value_len = je16_to_cpu(rx.value_len);
201 xd->data_crc = je32_to_cpu(rx.data_crc); 174 xd->data_crc = je32_to_cpu(rx.data_crc);
202 175
203 /* This JFFS2_NODETYPE_XATTR node is checked */
204 jeb = &c->blocks[ref_offset(xd->node) / c->sector_size];
205 totlen = PAD(je32_to_cpu(rx.totlen));
206
207 spin_lock(&c->erase_completion_lock); 176 spin_lock(&c->erase_completion_lock);
208 c->unchecked_size -= totlen; c->used_size += totlen; 177 complete:
209 jeb->unchecked_size -= totlen; jeb->used_size += totlen; 178 for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) {
210 xd->node->flash_offset = ref_offset(xd->node) | REF_PRISTINE; 179 jeb = &c->blocks[ref_offset(raw) / c->sector_size];
180 totlen = PAD(ref_totlen(c, jeb, raw));
181 if (ref_flags(raw) == REF_UNCHECKED) {
182 c->unchecked_size -= totlen; c->used_size += totlen;
183 jeb->unchecked_size -= totlen; jeb->used_size += totlen;
184 }
185 raw->flash_offset = ref_offset(raw) | ((xd->node==raw) ? REF_PRISTINE : REF_NORMAL);
186 }
211 spin_unlock(&c->erase_completion_lock); 187 spin_unlock(&c->erase_completion_lock);
212 188
213 /* unchecked xdatum is chained with c->xattr_unchecked */ 189 /* unchecked xdatum is chained with c->xattr_unchecked */
@@ -227,7 +203,6 @@ static int do_load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum
227 uint32_t crc, length; 203 uint32_t crc, length;
228 int i, ret, retry = 0; 204 int i, ret, retry = 0;
229 205
230 BUG_ON(!xd->node);
231 BUG_ON(ref_flags(xd->node) != REF_PRISTINE); 206 BUG_ON(ref_flags(xd->node) != REF_PRISTINE);
232 BUG_ON(!list_empty(&xd->xindex)); 207 BUG_ON(!list_empty(&xd->xindex));
233 retry: 208 retry:
@@ -253,6 +228,7 @@ static int do_load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum
253 " at %#08x, read: 0x%08x calculated: 0x%08x\n", 228 " at %#08x, read: 0x%08x calculated: 0x%08x\n",
254 ref_offset(xd->node), xd->data_crc, crc); 229 ref_offset(xd->node), xd->data_crc, crc);
255 kfree(data); 230 kfree(data);
231 xd->flags |= JFFS2_XFLAGS_INVALID;
256 return EIO; 232 return EIO;
257 } 233 }
258 234
@@ -286,16 +262,14 @@ static int load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *x
286 * rc > 0 : Unrecoverable error, this node should be deleted. 262 * rc > 0 : Unrecoverable error, this node should be deleted.
287 */ 263 */
288 int rc = 0; 264 int rc = 0;
289 BUG_ON(xd->xname); 265
290 if (!xd->node) 266 BUG_ON(xd->flags & JFFS2_XFLAGS_DEAD);
267 if (xd->xname)
268 return 0;
269 if (xd->flags & JFFS2_XFLAGS_INVALID)
291 return EIO; 270 return EIO;
292 if (unlikely(ref_flags(xd->node) != REF_PRISTINE)) { 271 if (unlikely(is_xattr_datum_unchecked(c, xd)))
293 rc = do_verify_xattr_datum(c, xd); 272 rc = do_verify_xattr_datum(c, xd);
294 if (rc > 0) {
295 list_del_init(&xd->xindex);
296 delete_xattr_datum_node(c, xd);
297 }
298 }
299 if (!rc) 273 if (!rc)
300 rc = do_load_xattr_datum(c, xd); 274 rc = do_load_xattr_datum(c, xd);
301 return rc; 275 return rc;
@@ -304,7 +278,6 @@ static int load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *x
304static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) 278static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
305{ 279{
306 /* must be called under down_write(xattr_sem) */ 280 /* must be called under down_write(xattr_sem) */
307 struct jffs2_raw_node_ref *raw;
308 struct jffs2_raw_xattr rx; 281 struct jffs2_raw_xattr rx;
309 struct kvec vecs[2]; 282 struct kvec vecs[2];
310 size_t length; 283 size_t length;
@@ -312,14 +285,16 @@ static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *x
312 uint32_t phys_ofs = write_ofs(c); 285 uint32_t phys_ofs = write_ofs(c);
313 286
314 BUG_ON(!xd->xname); 287 BUG_ON(!xd->xname);
288 BUG_ON(xd->flags & (JFFS2_XFLAGS_DEAD|JFFS2_XFLAGS_INVALID));
315 289
316 vecs[0].iov_base = &rx; 290 vecs[0].iov_base = &rx;
317 vecs[0].iov_len = PAD(sizeof(rx)); 291 vecs[0].iov_len = sizeof(rx);
318 vecs[1].iov_base = xd->xname; 292 vecs[1].iov_base = xd->xname;
319 vecs[1].iov_len = xd->name_len + 1 + xd->value_len; 293 vecs[1].iov_len = xd->name_len + 1 + xd->value_len;
320 totlen = vecs[0].iov_len + vecs[1].iov_len; 294 totlen = vecs[0].iov_len + vecs[1].iov_len;
321 295
322 /* Setup raw-xattr */ 296 /* Setup raw-xattr */
297 memset(&rx, 0, sizeof(rx));
323 rx.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); 298 rx.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
324 rx.nodetype = cpu_to_je16(JFFS2_NODETYPE_XATTR); 299 rx.nodetype = cpu_to_je16(JFFS2_NODETYPE_XATTR);
325 rx.totlen = cpu_to_je32(PAD(totlen)); 300 rx.totlen = cpu_to_je32(PAD(totlen));
@@ -343,14 +318,8 @@ static int save_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *x
343 318
344 return rc; 319 return rc;
345 } 320 }
346
347 /* success */ 321 /* success */
348 raw = jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, PAD(totlen), NULL); 322 jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, PAD(totlen), (void *)xd);
349 /* FIXME */ raw->next_in_ino = (void *)xd;
350
351 if (xd->node)
352 delete_xattr_datum_node(c, xd);
353 xd->node = raw;
354 323
355 dbg_xattr("success on saving xdatum (xid=%u, version=%u, xprefix=%u, xname='%s')\n", 324 dbg_xattr("success on saving xdatum (xid=%u, version=%u, xprefix=%u, xname='%s')\n",
356 xd->xid, xd->version, xd->xprefix, xd->xname); 325 xd->xid, xd->version, xd->xprefix, xd->xname);
@@ -377,7 +346,7 @@ static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c,
377 && xd->value_len==xsize 346 && xd->value_len==xsize
378 && !strcmp(xd->xname, xname) 347 && !strcmp(xd->xname, xname)
379 && !memcmp(xd->xvalue, xvalue, xsize)) { 348 && !memcmp(xd->xvalue, xvalue, xsize)) {
380 xd->refcnt++; 349 atomic_inc(&xd->refcnt);
381 return xd; 350 return xd;
382 } 351 }
383 } 352 }
@@ -397,7 +366,7 @@ static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c,
397 strcpy(data, xname); 366 strcpy(data, xname);
398 memcpy(data + name_len + 1, xvalue, xsize); 367 memcpy(data + name_len + 1, xvalue, xsize);
399 368
400 xd->refcnt = 1; 369 atomic_set(&xd->refcnt, 1);
401 xd->xid = ++c->highest_xid; 370 xd->xid = ++c->highest_xid;
402 xd->flags |= JFFS2_XFLAGS_HOT; 371 xd->flags |= JFFS2_XFLAGS_HOT;
403 xd->xprefix = xprefix; 372 xd->xprefix = xprefix;
@@ -426,20 +395,38 @@ static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c,
426 return xd; 395 return xd;
427} 396}
428 397
398static void unrefer_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
399{
400 /* must be called under down_write(xattr_sem) */
401 if (atomic_dec_and_lock(&xd->refcnt, &c->erase_completion_lock)) {
402 uint32_t xid = xd->xid, version = xd->version;
403
404 unload_xattr_datum(c, xd);
405 xd->flags |= JFFS2_XFLAGS_DEAD;
406 if (xd->node == (void *)xd) {
407 BUG_ON(!(xd->flags & JFFS2_XFLAGS_INVALID));
408 jffs2_free_xattr_datum(xd);
409 } else {
410 list_add(&xd->xindex, &c->xattr_dead_list);
411 }
412 spin_unlock(&c->erase_completion_lock);
413
414 dbg_xattr("xdatum(xid=%u, version=%u) was removed.\n", xid, version);
415 }
416}
417
429/* -------- xref related functions ------------------ 418/* -------- xref related functions ------------------
430 * verify_xattr_ref(c, ref) 419 * verify_xattr_ref(c, ref)
431 * is used to load xref information from medium. Because summary data does not 420 * is used to load xref information from medium. Because summary data does not
432 * contain xid/ino, it's necessary to verify once while mounting process. 421 * contain xid/ino, it's necessary to verify once while mounting process.
433 * delete_xattr_ref_node(c, ref)
434 * is used to delete a jffs2 node is dominated by xref. When EBS is enabled,
435 * it overwrites the obsolete node by myself.
436 * delete_xattr_ref(c, ref)
437 * is used to delete jffs2_xattr_ref object. If the reference counter of xdatum
438 * is refered by this xref become 0, delete_xattr_datum() is called later.
439 * save_xattr_ref(c, ref) 422 * save_xattr_ref(c, ref)
440 * is used to write xref to medium. 423 * is used to write xref to medium. If delete marker is marked, it write
424 * a delete marker of xref into medium.
441 * create_xattr_ref(c, ic, xd) 425 * create_xattr_ref(c, ic, xd)
442 * is used to create a new xref and write to medium. 426 * is used to create a new xref and write to medium.
427 * delete_xattr_ref(c, ref)
428 * is used to delete jffs2_xattr_ref. It marks xref XREF_DELETE_MARKER,
429 * and allows GC to reclaim those physical nodes.
443 * jffs2_xattr_delete_inode(c, ic) 430 * jffs2_xattr_delete_inode(c, ic)
444 * is called to remove xrefs related to obsolete inode when inode is unlinked. 431 * is called to remove xrefs related to obsolete inode when inode is unlinked.
445 * jffs2_xattr_free_inode(c, ic) 432 * jffs2_xattr_free_inode(c, ic)
@@ -450,25 +437,29 @@ static struct jffs2_xattr_datum *create_xattr_datum(struct jffs2_sb_info *c,
450static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref) 437static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
451{ 438{
452 struct jffs2_eraseblock *jeb; 439 struct jffs2_eraseblock *jeb;
440 struct jffs2_raw_node_ref *raw;
453 struct jffs2_raw_xref rr; 441 struct jffs2_raw_xref rr;
454 size_t readlen; 442 size_t readlen;
455 uint32_t crc, totlen; 443 uint32_t crc, offset, totlen;
456 int rc; 444 int rc;
457 445
458 BUG_ON(ref_flags(ref->node) != REF_UNCHECKED); 446 spin_lock(&c->erase_completion_lock);
447 if (ref_flags(ref->node) != REF_UNCHECKED)
448 goto complete;
449 offset = ref_offset(ref->node);
450 spin_unlock(&c->erase_completion_lock);
459 451
460 rc = jffs2_flash_read(c, ref_offset(ref->node), sizeof(rr), &readlen, (char *)&rr); 452 rc = jffs2_flash_read(c, offset, sizeof(rr), &readlen, (char *)&rr);
461 if (rc || sizeof(rr) != readlen) { 453 if (rc || sizeof(rr) != readlen) {
462 JFFS2_WARNING("jffs2_flash_read()=%d, req=%zu, read=%zu, at %#08x\n", 454 JFFS2_WARNING("jffs2_flash_read()=%d, req=%zu, read=%zu, at %#08x\n",
463 rc, sizeof(rr), readlen, ref_offset(ref->node)); 455 rc, sizeof(rr), readlen, offset);
464 return rc ? rc : -EIO; 456 return rc ? rc : -EIO;
465 } 457 }
466 /* obsolete node */ 458 /* obsolete node */
467 crc = crc32(0, &rr, sizeof(rr) - 4); 459 crc = crc32(0, &rr, sizeof(rr) - 4);
468 if (crc != je32_to_cpu(rr.node_crc)) { 460 if (crc != je32_to_cpu(rr.node_crc)) {
469 if (je32_to_cpu(rr.node_crc) != 0xffffffff) 461 JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n",
470 JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n", 462 offset, je32_to_cpu(rr.node_crc), crc);
471 ref_offset(ref->node), je32_to_cpu(rr.node_crc), crc);
472 return EIO; 463 return EIO;
473 } 464 }
474 if (je16_to_cpu(rr.magic) != JFFS2_MAGIC_BITMASK 465 if (je16_to_cpu(rr.magic) != JFFS2_MAGIC_BITMASK
@@ -476,22 +467,28 @@ static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref
476 || je32_to_cpu(rr.totlen) != PAD(sizeof(rr))) { 467 || je32_to_cpu(rr.totlen) != PAD(sizeof(rr))) {
477 JFFS2_ERROR("inconsistent xref at %#08x, magic=%#04x/%#04x, " 468 JFFS2_ERROR("inconsistent xref at %#08x, magic=%#04x/%#04x, "
478 "nodetype=%#04x/%#04x, totlen=%u/%zu\n", 469 "nodetype=%#04x/%#04x, totlen=%u/%zu\n",
479 ref_offset(ref->node), je16_to_cpu(rr.magic), JFFS2_MAGIC_BITMASK, 470 offset, je16_to_cpu(rr.magic), JFFS2_MAGIC_BITMASK,
480 je16_to_cpu(rr.nodetype), JFFS2_NODETYPE_XREF, 471 je16_to_cpu(rr.nodetype), JFFS2_NODETYPE_XREF,
481 je32_to_cpu(rr.totlen), PAD(sizeof(rr))); 472 je32_to_cpu(rr.totlen), PAD(sizeof(rr)));
482 return EIO; 473 return EIO;
483 } 474 }
484 ref->ino = je32_to_cpu(rr.ino); 475 ref->ino = je32_to_cpu(rr.ino);
485 ref->xid = je32_to_cpu(rr.xid); 476 ref->xid = je32_to_cpu(rr.xid);
486 477 ref->xseqno = je32_to_cpu(rr.xseqno);
487 /* fixup superblock/eraseblock info */ 478 if (ref->xseqno > c->highest_xseqno)
488 jeb = &c->blocks[ref_offset(ref->node) / c->sector_size]; 479 c->highest_xseqno = (ref->xseqno & ~XREF_DELETE_MARKER);
489 totlen = PAD(sizeof(rr));
490 480
491 spin_lock(&c->erase_completion_lock); 481 spin_lock(&c->erase_completion_lock);
492 c->unchecked_size -= totlen; c->used_size += totlen; 482 complete:
493 jeb->unchecked_size -= totlen; jeb->used_size += totlen; 483 for (raw=ref->node; raw != (void *)ref; raw=raw->next_in_ino) {
494 ref->node->flash_offset = ref_offset(ref->node) | REF_PRISTINE; 484 jeb = &c->blocks[ref_offset(raw) / c->sector_size];
485 totlen = PAD(ref_totlen(c, jeb, raw));
486 if (ref_flags(raw) == REF_UNCHECKED) {
487 c->unchecked_size -= totlen; c->used_size += totlen;
488 jeb->unchecked_size -= totlen; jeb->used_size += totlen;
489 }
490 raw->flash_offset = ref_offset(raw) | ((ref->node==raw) ? REF_PRISTINE : REF_NORMAL);
491 }
495 spin_unlock(&c->erase_completion_lock); 492 spin_unlock(&c->erase_completion_lock);
496 493
497 dbg_xattr("success on verifying xref (ino=%u, xid=%u) at %#08x\n", 494 dbg_xattr("success on verifying xref (ino=%u, xid=%u) at %#08x\n",
@@ -499,58 +496,12 @@ static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref
499 return 0; 496 return 0;
500} 497}
501 498
502static void delete_xattr_ref_node(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
503{
504 struct jffs2_raw_xref rr;
505 size_t length;
506 int rc;
507
508 if (jffs2_sum_active()) {
509 memset(&rr, 0xff, sizeof(rr));
510 rc = jffs2_flash_read(c, ref_offset(ref->node),
511 sizeof(struct jffs2_unknown_node),
512 &length, (char *)&rr);
513 if (rc || length != sizeof(struct jffs2_unknown_node)) {
514 JFFS2_ERROR("jffs2_flash_read()=%d, req=%zu, read=%zu at %#08x\n",
515 rc, sizeof(struct jffs2_unknown_node),
516 length, ref_offset(ref->node));
517 }
518 rc = jffs2_flash_write(c, ref_offset(ref->node), sizeof(rr),
519 &length, (char *)&rr);
520 if (rc || length != sizeof(struct jffs2_raw_xref)) {
521 JFFS2_ERROR("jffs2_flash_write()=%d, req=%zu, wrote=%zu at %#08x\n",
522 rc, sizeof(rr), length, ref_offset(ref->node));
523 }
524 }
525 spin_lock(&c->erase_completion_lock);
526 ref->node->next_in_ino = NULL;
527 spin_unlock(&c->erase_completion_lock);
528 jffs2_mark_node_obsolete(c, ref->node);
529 ref->node = NULL;
530}
531
532static void delete_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
533{
534 /* must be called under down_write(xattr_sem) */
535 struct jffs2_xattr_datum *xd;
536
537 BUG_ON(!ref->node);
538 delete_xattr_ref_node(c, ref);
539
540 xd = ref->xd;
541 xd->refcnt--;
542 if (!xd->refcnt)
543 delete_xattr_datum(c, xd);
544 jffs2_free_xattr_ref(ref);
545}
546
547static int save_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref) 499static int save_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
548{ 500{
549 /* must be called under down_write(xattr_sem) */ 501 /* must be called under down_write(xattr_sem) */
550 struct jffs2_raw_node_ref *raw;
551 struct jffs2_raw_xref rr; 502 struct jffs2_raw_xref rr;
552 size_t length; 503 size_t length;
553 uint32_t phys_ofs = write_ofs(c); 504 uint32_t xseqno, phys_ofs = write_ofs(c);
554 int ret; 505 int ret;
555 506
556 rr.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK); 507 rr.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
@@ -558,8 +509,16 @@ static int save_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
558 rr.totlen = cpu_to_je32(PAD(sizeof(rr))); 509 rr.totlen = cpu_to_je32(PAD(sizeof(rr)));
559 rr.hdr_crc = cpu_to_je32(crc32(0, &rr, sizeof(struct jffs2_unknown_node) - 4)); 510 rr.hdr_crc = cpu_to_je32(crc32(0, &rr, sizeof(struct jffs2_unknown_node) - 4));
560 511
561 rr.ino = cpu_to_je32(ref->ic->ino); 512 xseqno = (c->highest_xseqno += 2);
562 rr.xid = cpu_to_je32(ref->xd->xid); 513 if (is_xattr_ref_dead(ref)) {
514 xseqno |= XREF_DELETE_MARKER;
515 rr.ino = cpu_to_je32(ref->ino);
516 rr.xid = cpu_to_je32(ref->xid);
517 } else {
518 rr.ino = cpu_to_je32(ref->ic->ino);
519 rr.xid = cpu_to_je32(ref->xd->xid);
520 }
521 rr.xseqno = cpu_to_je32(xseqno);
563 rr.node_crc = cpu_to_je32(crc32(0, &rr, sizeof(rr) - 4)); 522 rr.node_crc = cpu_to_je32(crc32(0, &rr, sizeof(rr) - 4));
564 523
565 ret = jffs2_flash_write(c, phys_ofs, sizeof(rr), &length, (char *)&rr); 524 ret = jffs2_flash_write(c, phys_ofs, sizeof(rr), &length, (char *)&rr);
@@ -572,12 +531,9 @@ static int save_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
572 531
573 return ret; 532 return ret;
574 } 533 }
575 534 /* success */
576 raw = jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, PAD(sizeof(rr)), NULL); 535 ref->xseqno = xseqno;
577 /* FIXME */ raw->next_in_ino = (void *)ref; 536 jffs2_add_physical_node_ref(c, phys_ofs | REF_PRISTINE, PAD(sizeof(rr)), (void *)ref);
578 if (ref->node)
579 delete_xattr_ref_node(c, ref);
580 ref->node = raw;
581 537
582 dbg_xattr("success on saving xref (ino=%u, xid=%u)\n", ref->ic->ino, ref->xd->xid); 538 dbg_xattr("success on saving xref (ino=%u, xid=%u)\n", ref->ic->ino, ref->xd->xid);
583 539
@@ -610,6 +566,26 @@ static struct jffs2_xattr_ref *create_xattr_ref(struct jffs2_sb_info *c, struct
610 return ref; /* success */ 566 return ref; /* success */
611} 567}
612 568
569static void delete_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
570{
571 /* must be called under down_write(xattr_sem) */
572 struct jffs2_xattr_datum *xd;
573
574 xd = ref->xd;
575 ref->xseqno |= XREF_DELETE_MARKER;
576 ref->ino = ref->ic->ino;
577 ref->xid = ref->xd->xid;
578 spin_lock(&c->erase_completion_lock);
579 ref->next = c->xref_dead_list;
580 c->xref_dead_list = ref;
581 spin_unlock(&c->erase_completion_lock);
582
583 dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) was removed.\n",
584 ref->ino, ref->xid, ref->xseqno);
585
586 unrefer_xattr_datum(c, xd);
587}
588
613void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic) 589void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic)
614{ 590{
615 /* It's called from jffs2_clear_inode() on inode removing. 591 /* It's called from jffs2_clear_inode() on inode removing.
@@ -638,8 +614,7 @@ void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *i
638 for (ref = ic->xref; ref; ref = _ref) { 614 for (ref = ic->xref; ref; ref = _ref) {
639 _ref = ref->next; 615 _ref = ref->next;
640 xd = ref->xd; 616 xd = ref->xd;
641 xd->refcnt--; 617 if (atomic_dec_and_test(&xd->refcnt)) {
642 if (!xd->refcnt) {
643 unload_xattr_datum(c, xd); 618 unload_xattr_datum(c, xd);
644 jffs2_free_xattr_datum(xd); 619 jffs2_free_xattr_datum(xd);
645 } 620 }
@@ -655,7 +630,7 @@ static int check_xattr_ref_inode(struct jffs2_sb_info *c, struct jffs2_inode_cac
655 * duplicate name/value pairs. If duplicate name/value pair would be found, 630 * duplicate name/value pairs. If duplicate name/value pair would be found,
656 * one will be removed. 631 * one will be removed.
657 */ 632 */
658 struct jffs2_xattr_ref *ref, *cmp, **pref; 633 struct jffs2_xattr_ref *ref, *cmp, **pref, **pcmp;
659 int rc = 0; 634 int rc = 0;
660 635
661 if (likely(ic->flags & INO_FLAGS_XATTR_CHECKED)) 636 if (likely(ic->flags & INO_FLAGS_XATTR_CHECKED))
@@ -673,13 +648,13 @@ static int check_xattr_ref_inode(struct jffs2_sb_info *c, struct jffs2_inode_cac
673 } else if (unlikely(rc < 0)) 648 } else if (unlikely(rc < 0))
674 goto out; 649 goto out;
675 } 650 }
676 for (cmp=ref->next, pref=&ref->next; cmp; pref=&cmp->next, cmp=cmp->next) { 651 for (cmp=ref->next, pcmp=&ref->next; cmp; pcmp=&cmp->next, cmp=cmp->next) {
677 if (!cmp->xd->xname) { 652 if (!cmp->xd->xname) {
678 ref->xd->flags |= JFFS2_XFLAGS_BIND; 653 ref->xd->flags |= JFFS2_XFLAGS_BIND;
679 rc = load_xattr_datum(c, cmp->xd); 654 rc = load_xattr_datum(c, cmp->xd);
680 ref->xd->flags &= ~JFFS2_XFLAGS_BIND; 655 ref->xd->flags &= ~JFFS2_XFLAGS_BIND;
681 if (unlikely(rc > 0)) { 656 if (unlikely(rc > 0)) {
682 *pref = cmp->next; 657 *pcmp = cmp->next;
683 delete_xattr_ref(c, cmp); 658 delete_xattr_ref(c, cmp);
684 goto retry; 659 goto retry;
685 } else if (unlikely(rc < 0)) 660 } else if (unlikely(rc < 0))
@@ -687,8 +662,13 @@ static int check_xattr_ref_inode(struct jffs2_sb_info *c, struct jffs2_inode_cac
687 } 662 }
688 if (ref->xd->xprefix == cmp->xd->xprefix 663 if (ref->xd->xprefix == cmp->xd->xprefix
689 && !strcmp(ref->xd->xname, cmp->xd->xname)) { 664 && !strcmp(ref->xd->xname, cmp->xd->xname)) {
690 *pref = cmp->next; 665 if (ref->xseqno > cmp->xseqno) {
691 delete_xattr_ref(c, cmp); 666 *pcmp = cmp->next;
667 delete_xattr_ref(c, cmp);
668 } else {
669 *pref = ref->next;
670 delete_xattr_ref(c, ref);
671 }
692 goto retry; 672 goto retry;
693 } 673 }
694 } 674 }
@@ -719,9 +699,13 @@ void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c)
719 for (i=0; i < XATTRINDEX_HASHSIZE; i++) 699 for (i=0; i < XATTRINDEX_HASHSIZE; i++)
720 INIT_LIST_HEAD(&c->xattrindex[i]); 700 INIT_LIST_HEAD(&c->xattrindex[i]);
721 INIT_LIST_HEAD(&c->xattr_unchecked); 701 INIT_LIST_HEAD(&c->xattr_unchecked);
702 INIT_LIST_HEAD(&c->xattr_dead_list);
703 c->xref_dead_list = NULL;
722 c->xref_temp = NULL; 704 c->xref_temp = NULL;
723 705
724 init_rwsem(&c->xattr_sem); 706 init_rwsem(&c->xattr_sem);
707 c->highest_xid = 0;
708 c->highest_xseqno = 0;
725 c->xdatum_mem_usage = 0; 709 c->xdatum_mem_usage = 0;
726 c->xdatum_mem_threshold = 32 * 1024; /* Default 32KB */ 710 c->xdatum_mem_threshold = 32 * 1024; /* Default 32KB */
727} 711}
@@ -751,7 +735,11 @@ void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c)
751 _ref = ref->next; 735 _ref = ref->next;
752 jffs2_free_xattr_ref(ref); 736 jffs2_free_xattr_ref(ref);
753 } 737 }
754 c->xref_temp = NULL; 738
739 for (ref=c->xref_dead_list; ref; ref = _ref) {
740 _ref = ref->next;
741 jffs2_free_xattr_ref(ref);
742 }
755 743
756 for (i=0; i < XATTRINDEX_HASHSIZE; i++) { 744 for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
757 list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) { 745 list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) {
@@ -761,100 +749,143 @@ void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c)
761 jffs2_free_xattr_datum(xd); 749 jffs2_free_xattr_datum(xd);
762 } 750 }
763 } 751 }
752
753 list_for_each_entry_safe(xd, _xd, &c->xattr_dead_list, xindex) {
754 list_del(&xd->xindex);
755 jffs2_free_xattr_datum(xd);
756 }
764} 757}
765 758
759#define XREF_TMPHASH_SIZE (128)
766void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c) 760void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
767{ 761{
768 struct jffs2_xattr_ref *ref, *_ref; 762 struct jffs2_xattr_ref *ref, *_ref;
763 struct jffs2_xattr_ref *xref_tmphash[XREF_TMPHASH_SIZE];
769 struct jffs2_xattr_datum *xd, *_xd; 764 struct jffs2_xattr_datum *xd, *_xd;
770 struct jffs2_inode_cache *ic; 765 struct jffs2_inode_cache *ic;
771 int i, xdatum_count =0, xdatum_unchecked_count = 0, xref_count = 0; 766 struct jffs2_raw_node_ref *raw;
767 int i, xdatum_count = 0, xdatum_unchecked_count = 0, xref_count = 0;
768 int xdatum_orphan_count = 0, xref_orphan_count = 0, xref_dead_count = 0;
772 769
773 BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING)); 770 BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING));
774 771
775 /* Phase.1 */ 772 /* Phase.1 : Merge same xref */
773 for (i=0; i < XREF_TMPHASH_SIZE; i++)
774 xref_tmphash[i] = NULL;
776 for (ref=c->xref_temp; ref; ref=_ref) { 775 for (ref=c->xref_temp; ref; ref=_ref) {
776 struct jffs2_xattr_ref *tmp;
777
777 _ref = ref->next; 778 _ref = ref->next;
778 /* checking REF_UNCHECKED nodes */
779 if (ref_flags(ref->node) != REF_PRISTINE) { 779 if (ref_flags(ref->node) != REF_PRISTINE) {
780 if (verify_xattr_ref(c, ref)) { 780 if (verify_xattr_ref(c, ref)) {
781 delete_xattr_ref_node(c, ref); 781 BUG_ON(ref->node->next_in_ino != (void *)ref);
782 ref->node->next_in_ino = NULL;
783 jffs2_mark_node_obsolete(c, ref->node);
782 jffs2_free_xattr_ref(ref); 784 jffs2_free_xattr_ref(ref);
783 continue; 785 continue;
784 } 786 }
785 } 787 }
786 /* At this point, ref->xid and ref->ino contain XID and inode number. 788
787 ref->xd and ref->ic are not valid yet. */ 789 i = (ref->ino ^ ref->xid) % XREF_TMPHASH_SIZE;
788 xd = jffs2_find_xattr_datum(c, ref->xid); 790 for (tmp=xref_tmphash[i]; tmp; tmp=tmp->next) {
789 ic = jffs2_get_ino_cache(c, ref->ino); 791 if (tmp->ino == ref->ino && tmp->xid == ref->xid)
790 if (!xd || !ic) { 792 break;
791 if (ref_flags(ref->node) != REF_UNCHECKED) 793 }
792 JFFS2_WARNING("xref(ino=%u, xid=%u) is orphan. \n", 794 if (tmp) {
793 ref->ino, ref->xid); 795 raw = ref->node;
794 delete_xattr_ref_node(c, ref); 796 if (ref->xseqno > tmp->xseqno) {
797 tmp->xseqno = ref->xseqno;
798 raw->next_in_ino = tmp->node;
799 tmp->node = raw;
800 } else {
801 raw->next_in_ino = tmp->node->next_in_ino;
802 tmp->node->next_in_ino = raw;
803 }
795 jffs2_free_xattr_ref(ref); 804 jffs2_free_xattr_ref(ref);
796 continue; 805 continue;
806 } else {
807 ref->next = xref_tmphash[i];
808 xref_tmphash[i] = ref;
797 } 809 }
798 ref->xd = xd;
799 ref->ic = ic;
800 xd->refcnt++;
801 ref->next = ic->xref;
802 ic->xref = ref;
803 xref_count++;
804 } 810 }
805 c->xref_temp = NULL; 811 c->xref_temp = NULL;
806 /* After this, ref->xid/ino are NEVER used. */
807 812
808 /* Phase.2 */ 813 /* Phase.2 : Bind xref with inode_cache and xattr_datum */
814 for (i=0; i < XREF_TMPHASH_SIZE; i++) {
815 for (ref=xref_tmphash[i]; ref; ref=_ref) {
816 xref_count++;
817 _ref = ref->next;
818 if (is_xattr_ref_dead(ref)) {
819 ref->next = c->xref_dead_list;
820 c->xref_dead_list = ref;
821 xref_dead_count++;
822 continue;
823 }
824 /* At this point, ref->xid and ref->ino contain XID and inode number.
825 ref->xd and ref->ic are not valid yet. */
826 xd = jffs2_find_xattr_datum(c, ref->xid);
827 ic = jffs2_get_ino_cache(c, ref->ino);
828 if (!xd || !ic) {
829 dbg_xattr("xref(ino=%u, xid=%u, xseqno=%u) is orphan.\n",
830 ref->ino, ref->xid, ref->xseqno);
831 ref->xseqno |= XREF_DELETE_MARKER;
832 ref->next = c->xref_dead_list;
833 c->xref_dead_list = ref;
834 xref_orphan_count++;
835 continue;
836 }
837 ref->xd = xd;
838 ref->ic = ic;
839 atomic_inc(&xd->refcnt);
840 ref->next = ic->xref;
841 ic->xref = ref;
842 }
843 }
844
845 /* Phase.3 : Link unchecked xdatum to xattr_unchecked list */
809 for (i=0; i < XATTRINDEX_HASHSIZE; i++) { 846 for (i=0; i < XATTRINDEX_HASHSIZE; i++) {
810 list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) { 847 list_for_each_entry_safe(xd, _xd, &c->xattrindex[i], xindex) {
848 xdatum_count++;
811 list_del_init(&xd->xindex); 849 list_del_init(&xd->xindex);
812 if (!xd->refcnt) { 850 if (!atomic_read(&xd->refcnt)) {
813 if (ref_flags(xd->node) != REF_UNCHECKED) 851 dbg_xattr("xdatum(xid=%u, version=%u) is orphan.\n",
814 JFFS2_WARNING("orphan xdatum(xid=%u, version=%u) at %#08x\n", 852 xd->xid, xd->version);
815 xd->xid, xd->version, ref_offset(xd->node)); 853 xd->flags |= JFFS2_XFLAGS_DEAD;
816 delete_xattr_datum(c, xd); 854 list_add(&xd->xindex, &c->xattr_unchecked);
855 xdatum_orphan_count++;
817 continue; 856 continue;
818 } 857 }
819 if (ref_flags(xd->node) != REF_PRISTINE) { 858 if (is_xattr_datum_unchecked(c, xd)) {
820 dbg_xattr("unchecked xdatum(xid=%u) at %#08x\n", 859 dbg_xattr("unchecked xdatum(xid=%u, version=%u)\n",
821 xd->xid, ref_offset(xd->node)); 860 xd->xid, xd->version);
822 list_add(&xd->xindex, &c->xattr_unchecked); 861 list_add(&xd->xindex, &c->xattr_unchecked);
823 xdatum_unchecked_count++; 862 xdatum_unchecked_count++;
824 } 863 }
825 xdatum_count++;
826 } 864 }
827 } 865 }
828 /* build complete */ 866 /* build complete */
829 JFFS2_NOTICE("complete building xattr subsystem, %u of xdatum (%u unchecked) and " 867 JFFS2_NOTICE("complete building xattr subsystem, %u of xdatum"
830 "%u of xref found.\n", xdatum_count, xdatum_unchecked_count, xref_count); 868 " (%u unchecked, %u orphan) and "
869 "%u of xref (%u dead, %u orphan) found.\n",
870 xdatum_count, xdatum_unchecked_count, xdatum_orphan_count,
871 xref_count, xref_dead_count, xref_orphan_count);
831} 872}
832 873
833struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c, 874struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c,
834 uint32_t xid, uint32_t version) 875 uint32_t xid, uint32_t version)
835{ 876{
836 struct jffs2_xattr_datum *xd, *_xd; 877 struct jffs2_xattr_datum *xd;
837 878
838 _xd = jffs2_find_xattr_datum(c, xid); 879 xd = jffs2_find_xattr_datum(c, xid);
839 if (_xd) { 880 if (!xd) {
840 dbg_xattr("duplicate xdatum (xid=%u, version=%u/%u) at %#08x\n", 881 xd = jffs2_alloc_xattr_datum();
841 xid, version, _xd->version, ref_offset(_xd->node)); 882 if (!xd)
842 if (version < _xd->version) 883 return ERR_PTR(-ENOMEM);
843 return ERR_PTR(-EEXIST); 884 xd->xid = xid;
844 } 885 xd->version = version;
845 xd = jffs2_alloc_xattr_datum(); 886 if (xd->xid > c->highest_xid)
846 if (!xd) 887 c->highest_xid = xd->xid;
847 return ERR_PTR(-ENOMEM); 888 list_add_tail(&xd->xindex, &c->xattrindex[xid % XATTRINDEX_HASHSIZE]);
848 xd->xid = xid;
849 xd->version = version;
850 if (xd->xid > c->highest_xid)
851 c->highest_xid = xd->xid;
852 list_add_tail(&xd->xindex, &c->xattrindex[xid % XATTRINDEX_HASHSIZE]);
853
854 if (_xd) {
855 list_del_init(&_xd->xindex);
856 delete_xattr_datum_node(c, _xd);
857 jffs2_free_xattr_datum(_xd);
858 } 889 }
859 return xd; 890 return xd;
860} 891}
@@ -1080,9 +1111,22 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
1080 goto out; 1111 goto out;
1081 } 1112 }
1082 if (!buffer) { 1113 if (!buffer) {
1083 *pref = ref->next; 1114 ref->ino = ic->ino;
1084 delete_xattr_ref(c, ref); 1115 ref->xid = xd->xid;
1085 rc = 0; 1116 ref->xseqno |= XREF_DELETE_MARKER;
1117 rc = save_xattr_ref(c, ref);
1118 if (!rc) {
1119 *pref = ref->next;
1120 spin_lock(&c->erase_completion_lock);
1121 ref->next = c->xref_dead_list;
1122 c->xref_dead_list = ref;
1123 spin_unlock(&c->erase_completion_lock);
1124 unrefer_xattr_datum(c, xd);
1125 } else {
1126 ref->ic = ic;
1127 ref->xd = xd;
1128 ref->xseqno &= ~XREF_DELETE_MARKER;
1129 }
1086 goto out; 1130 goto out;
1087 } 1131 }
1088 goto found; 1132 goto found;
@@ -1094,7 +1138,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
1094 goto out; 1138 goto out;
1095 } 1139 }
1096 if (!buffer) { 1140 if (!buffer) {
1097 rc = -EINVAL; 1141 rc = -ENODATA;
1098 goto out; 1142 goto out;
1099 } 1143 }
1100 found: 1144 found:
@@ -1110,16 +1154,13 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
1110 request = PAD(sizeof(struct jffs2_raw_xref)); 1154 request = PAD(sizeof(struct jffs2_raw_xref));
1111 rc = jffs2_reserve_space(c, request, &length, 1155 rc = jffs2_reserve_space(c, request, &length,
1112 ALLOC_NORMAL, JFFS2_SUMMARY_XREF_SIZE); 1156 ALLOC_NORMAL, JFFS2_SUMMARY_XREF_SIZE);
1157 down_write(&c->xattr_sem);
1113 if (rc) { 1158 if (rc) {
1114 JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request); 1159 JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, request);
1115 down_write(&c->xattr_sem); 1160 unrefer_xattr_datum(c, xd);
1116 xd->refcnt--;
1117 if (!xd->refcnt)
1118 delete_xattr_datum(c, xd);
1119 up_write(&c->xattr_sem); 1161 up_write(&c->xattr_sem);
1120 return rc; 1162 return rc;
1121 } 1163 }
1122 down_write(&c->xattr_sem);
1123 if (ref) 1164 if (ref)
1124 *pref = ref->next; 1165 *pref = ref->next;
1125 newref = create_xattr_ref(c, ic, xd); 1166 newref = create_xattr_ref(c, ic, xd);
@@ -1129,9 +1170,7 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
1129 ic->xref = ref; 1170 ic->xref = ref;
1130 } 1171 }
1131 rc = PTR_ERR(newref); 1172 rc = PTR_ERR(newref);
1132 xd->refcnt--; 1173 unrefer_xattr_datum(c, xd);
1133 if (!xd->refcnt)
1134 delete_xattr_datum(c, xd);
1135 } else if (ref) { 1174 } else if (ref) {
1136 delete_xattr_ref(c, ref); 1175 delete_xattr_ref(c, ref);
1137 } 1176 }
@@ -1142,38 +1181,40 @@ int do_jffs2_setxattr(struct inode *inode, int xprefix, const char *xname,
1142} 1181}
1143 1182
1144/* -------- garbage collector functions ------------- 1183/* -------- garbage collector functions -------------
1145 * jffs2_garbage_collect_xattr_datum(c, xd) 1184 * jffs2_garbage_collect_xattr_datum(c, xd, raw)
1146 * is used to move xdatum into new node. 1185 * is used to move xdatum into new node.
1147 * jffs2_garbage_collect_xattr_ref(c, ref) 1186 * jffs2_garbage_collect_xattr_ref(c, ref, raw)
1148 * is used to move xref into new node. 1187 * is used to move xref into new node.
1149 * jffs2_verify_xattr(c) 1188 * jffs2_verify_xattr(c)
1150 * is used to call do_verify_xattr_datum() before garbage collecting. 1189 * is used to call do_verify_xattr_datum() before garbage collecting.
1190 * jffs2_release_xattr_datum(c, xd)
1191 * is used to release an in-memory object of xdatum.
1192 * jffs2_release_xattr_ref(c, ref)
1193 * is used to release an in-memory object of xref.
1151 * -------------------------------------------------- */ 1194 * -------------------------------------------------- */
1152int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd) 1195int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd,
1196 struct jffs2_raw_node_ref *raw)
1153{ 1197{
1154 uint32_t totlen, length, old_ofs; 1198 uint32_t totlen, length, old_ofs;
1155 int rc = -EINVAL; 1199 int rc = 0;
1156 1200
1157 down_write(&c->xattr_sem); 1201 down_write(&c->xattr_sem);
1158 BUG_ON(!xd->node); 1202 if (xd->node != raw)
1159 1203 goto out;
1160 old_ofs = ref_offset(xd->node); 1204 if (xd->flags & (JFFS2_XFLAGS_DEAD|JFFS2_XFLAGS_INVALID))
1161 totlen = ref_totlen(c, c->gcblock, xd->node);
1162 if (totlen < sizeof(struct jffs2_raw_xattr))
1163 goto out; 1205 goto out;
1164 1206
1165 if (!xd->xname) { 1207 rc = load_xattr_datum(c, xd);
1166 rc = load_xattr_datum(c, xd); 1208 if (unlikely(rc)) {
1167 if (unlikely(rc > 0)) { 1209 rc = (rc > 0) ? 0 : rc;
1168 delete_xattr_datum_node(c, xd); 1210 goto out;
1169 rc = 0;
1170 goto out;
1171 } else if (unlikely(rc < 0))
1172 goto out;
1173 } 1211 }
1212 old_ofs = ref_offset(xd->node);
1213 totlen = PAD(sizeof(struct jffs2_raw_xattr)
1214 + xd->name_len + 1 + xd->value_len);
1174 rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XATTR_SIZE); 1215 rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XATTR_SIZE);
1175 if (rc || length < totlen) { 1216 if (rc) {
1176 JFFS2_WARNING("jffs2_reserve_space()=%d, request=%u\n", rc, totlen); 1217 JFFS2_WARNING("jffs2_reserve_space_gc()=%d, request=%u\n", rc, totlen);
1177 rc = rc ? rc : -EBADFD; 1218 rc = rc ? rc : -EBADFD;
1178 goto out; 1219 goto out;
1179 } 1220 }
@@ -1182,27 +1223,32 @@ int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xatt
1182 dbg_xattr("xdatum (xid=%u, version=%u) GC'ed from %#08x to %08x\n", 1223 dbg_xattr("xdatum (xid=%u, version=%u) GC'ed from %#08x to %08x\n",
1183 xd->xid, xd->version, old_ofs, ref_offset(xd->node)); 1224 xd->xid, xd->version, old_ofs, ref_offset(xd->node));
1184 out: 1225 out:
1226 if (!rc)
1227 jffs2_mark_node_obsolete(c, raw);
1185 up_write(&c->xattr_sem); 1228 up_write(&c->xattr_sem);
1186 return rc; 1229 return rc;
1187} 1230}
1188 1231
1189 1232int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref,
1190int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref) 1233 struct jffs2_raw_node_ref *raw)
1191{ 1234{
1192 uint32_t totlen, length, old_ofs; 1235 uint32_t totlen, length, old_ofs;
1193 int rc = -EINVAL; 1236 int rc = 0;
1194 1237
1195 down_write(&c->xattr_sem); 1238 down_write(&c->xattr_sem);
1196 BUG_ON(!ref->node); 1239 BUG_ON(!ref->node);
1197 1240
1241 if (ref->node != raw)
1242 goto out;
1243 if (is_xattr_ref_dead(ref) && (raw->next_in_ino == (void *)ref))
1244 goto out;
1245
1198 old_ofs = ref_offset(ref->node); 1246 old_ofs = ref_offset(ref->node);
1199 totlen = ref_totlen(c, c->gcblock, ref->node); 1247 totlen = ref_totlen(c, c->gcblock, ref->node);
1200 if (totlen != sizeof(struct jffs2_raw_xref))
1201 goto out;
1202 1248
1203 rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XREF_SIZE); 1249 rc = jffs2_reserve_space_gc(c, totlen, &length, JFFS2_SUMMARY_XREF_SIZE);
1204 if (rc || length < totlen) { 1250 if (rc) {
1205 JFFS2_WARNING("%s: jffs2_reserve_space() = %d, request = %u\n", 1251 JFFS2_WARNING("%s: jffs2_reserve_space_gc() = %d, request = %u\n",
1206 __FUNCTION__, rc, totlen); 1252 __FUNCTION__, rc, totlen);
1207 rc = rc ? rc : -EBADFD; 1253 rc = rc ? rc : -EBADFD;
1208 goto out; 1254 goto out;
@@ -1212,6 +1258,8 @@ int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_
1212 dbg_xattr("xref (ino=%u, xid=%u) GC'ed from %#08x to %08x\n", 1258 dbg_xattr("xref (ino=%u, xid=%u) GC'ed from %#08x to %08x\n",
1213 ref->ic->ino, ref->xd->xid, old_ofs, ref_offset(ref->node)); 1259 ref->ic->ino, ref->xd->xid, old_ofs, ref_offset(ref->node));
1214 out: 1260 out:
1261 if (!rc)
1262 jffs2_mark_node_obsolete(c, raw);
1215 up_write(&c->xattr_sem); 1263 up_write(&c->xattr_sem);
1216 return rc; 1264 return rc;
1217} 1265}
@@ -1219,20 +1267,59 @@ int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_
1219int jffs2_verify_xattr(struct jffs2_sb_info *c) 1267int jffs2_verify_xattr(struct jffs2_sb_info *c)
1220{ 1268{
1221 struct jffs2_xattr_datum *xd, *_xd; 1269 struct jffs2_xattr_datum *xd, *_xd;
1270 struct jffs2_eraseblock *jeb;
1271 struct jffs2_raw_node_ref *raw;
1272 uint32_t totlen;
1222 int rc; 1273 int rc;
1223 1274
1224 down_write(&c->xattr_sem); 1275 down_write(&c->xattr_sem);
1225 list_for_each_entry_safe(xd, _xd, &c->xattr_unchecked, xindex) { 1276 list_for_each_entry_safe(xd, _xd, &c->xattr_unchecked, xindex) {
1226 rc = do_verify_xattr_datum(c, xd); 1277 rc = do_verify_xattr_datum(c, xd);
1227 if (rc == 0) { 1278 if (rc < 0)
1228 list_del_init(&xd->xindex); 1279 continue;
1229 break; 1280 list_del_init(&xd->xindex);
1230 } else if (rc > 0) { 1281 spin_lock(&c->erase_completion_lock);
1231 list_del_init(&xd->xindex); 1282 for (raw=xd->node; raw != (void *)xd; raw=raw->next_in_ino) {
1232 delete_xattr_datum_node(c, xd); 1283 if (ref_flags(raw) != REF_UNCHECKED)
1284 continue;
1285 jeb = &c->blocks[ref_offset(raw) / c->sector_size];
1286 totlen = PAD(ref_totlen(c, jeb, raw));
1287 c->unchecked_size -= totlen; c->used_size += totlen;
1288 jeb->unchecked_size -= totlen; jeb->used_size += totlen;
1289 raw->flash_offset = ref_offset(raw)
1290 | ((xd->node == (void *)raw) ? REF_PRISTINE : REF_NORMAL);
1233 } 1291 }
1292 if (xd->flags & JFFS2_XFLAGS_DEAD)
1293 list_add(&xd->xindex, &c->xattr_dead_list);
1294 spin_unlock(&c->erase_completion_lock);
1234 } 1295 }
1235 up_write(&c->xattr_sem); 1296 up_write(&c->xattr_sem);
1236
1237 return list_empty(&c->xattr_unchecked) ? 1 : 0; 1297 return list_empty(&c->xattr_unchecked) ? 1 : 0;
1238} 1298}
1299
1300void jffs2_release_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd)
1301{
1302 /* must be called under spin_lock(&c->erase_completion_lock) */
1303 if (atomic_read(&xd->refcnt) || xd->node != (void *)xd)
1304 return;
1305
1306 list_del(&xd->xindex);
1307 jffs2_free_xattr_datum(xd);
1308}
1309
1310void jffs2_release_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref)
1311{
1312 /* must be called under spin_lock(&c->erase_completion_lock) */
1313 struct jffs2_xattr_ref *tmp, **ptmp;
1314
1315 if (ref->node != (void *)ref)
1316 return;
1317
1318 for (tmp=c->xref_dead_list, ptmp=&c->xref_dead_list; tmp; ptmp=&tmp->next, tmp=tmp->next) {
1319 if (ref == tmp) {
1320 *ptmp = tmp->next;
1321 break;
1322 }
1323 }
1324 jffs2_free_xattr_ref(ref);
1325}
diff --git a/fs/jffs2/xattr.h b/fs/jffs2/xattr.h
index 2c199856c582..06a5c69dcf8b 100644
--- a/fs/jffs2/xattr.h
+++ b/fs/jffs2/xattr.h
@@ -16,6 +16,8 @@
16 16
17#define JFFS2_XFLAGS_HOT (0x01) /* This datum is HOT */ 17#define JFFS2_XFLAGS_HOT (0x01) /* This datum is HOT */
18#define JFFS2_XFLAGS_BIND (0x02) /* This datum is not reclaimed */ 18#define JFFS2_XFLAGS_BIND (0x02) /* This datum is not reclaimed */
19#define JFFS2_XFLAGS_DEAD (0x40) /* This datum is already dead */
20#define JFFS2_XFLAGS_INVALID (0x80) /* This datum contains crc error */
19 21
20struct jffs2_xattr_datum 22struct jffs2_xattr_datum
21{ 23{
@@ -23,10 +25,10 @@ struct jffs2_xattr_datum
23 struct jffs2_raw_node_ref *node; 25 struct jffs2_raw_node_ref *node;
24 uint8_t class; 26 uint8_t class;
25 uint8_t flags; 27 uint8_t flags;
26 uint16_t xprefix; /* see JFFS2_XATTR_PREFIX_* */ 28 uint16_t xprefix; /* see JFFS2_XATTR_PREFIX_* */
27 29
28 struct list_head xindex; /* chained from c->xattrindex[n] */ 30 struct list_head xindex; /* chained from c->xattrindex[n] */
29 uint32_t refcnt; /* # of xattr_ref refers this */ 31 atomic_t refcnt; /* # of xattr_ref refers this */
30 uint32_t xid; 32 uint32_t xid;
31 uint32_t version; 33 uint32_t version;
32 34
@@ -47,6 +49,7 @@ struct jffs2_xattr_ref
47 uint8_t flags; /* Currently unused */ 49 uint8_t flags; /* Currently unused */
48 u16 unused; 50 u16 unused;
49 51
52 uint32_t xseqno;
50 union { 53 union {
51 struct jffs2_inode_cache *ic; /* reference to jffs2_inode_cache */ 54 struct jffs2_inode_cache *ic; /* reference to jffs2_inode_cache */
52 uint32_t ino; /* only used in scanning/building */ 55 uint32_t ino; /* only used in scanning/building */
@@ -58,6 +61,12 @@ struct jffs2_xattr_ref
58 struct jffs2_xattr_ref *next; /* chained from ic->xref_list */ 61 struct jffs2_xattr_ref *next; /* chained from ic->xref_list */
59}; 62};
60 63
64#define XREF_DELETE_MARKER (0x00000001)
65static inline int is_xattr_ref_dead(struct jffs2_xattr_ref *ref)
66{
67 return ((ref->xseqno & XREF_DELETE_MARKER) != 0);
68}
69
61#ifdef CONFIG_JFFS2_FS_XATTR 70#ifdef CONFIG_JFFS2_FS_XATTR
62 71
63extern void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c); 72extern void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c);
@@ -70,9 +79,13 @@ extern struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c
70extern void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic); 79extern void jffs2_xattr_delete_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic);
71extern void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic); 80extern void jffs2_xattr_free_inode(struct jffs2_sb_info *c, struct jffs2_inode_cache *ic);
72 81
73extern int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd); 82extern int jffs2_garbage_collect_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd,
74extern int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref); 83 struct jffs2_raw_node_ref *raw);
84extern int jffs2_garbage_collect_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref,
85 struct jffs2_raw_node_ref *raw);
75extern int jffs2_verify_xattr(struct jffs2_sb_info *c); 86extern int jffs2_verify_xattr(struct jffs2_sb_info *c);
87extern void jffs2_release_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *xd);
88extern void jffs2_release_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref);
76 89
77extern int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname, 90extern int do_jffs2_getxattr(struct inode *inode, int xprefix, const char *xname,
78 char *buffer, size_t size); 91 char *buffer, size_t size);
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index 04eb78f1252e..43e3f566aad6 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -305,7 +305,7 @@ static ssize_t jfs_direct_IO(int rw, struct kiocb *iocb,
305 offset, nr_segs, jfs_get_block, NULL); 305 offset, nr_segs, jfs_get_block, NULL);
306} 306}
307 307
308struct address_space_operations jfs_aops = { 308const struct address_space_operations jfs_aops = {
309 .readpage = jfs_readpage, 309 .readpage = jfs_readpage,
310 .readpages = jfs_readpages, 310 .readpages = jfs_readpages,
311 .writepage = jfs_writepage, 311 .writepage = jfs_writepage,
diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h
index c30072674464..b5c7da6190dc 100644
--- a/fs/jfs/jfs_inode.h
+++ b/fs/jfs/jfs_inode.h
@@ -33,7 +33,7 @@ extern void jfs_free_zero_link(struct inode *);
33extern struct dentry *jfs_get_parent(struct dentry *dentry); 33extern struct dentry *jfs_get_parent(struct dentry *dentry);
34extern void jfs_set_inode_flags(struct inode *); 34extern void jfs_set_inode_flags(struct inode *);
35 35
36extern struct address_space_operations jfs_aops; 36extern const struct address_space_operations jfs_aops;
37extern struct inode_operations jfs_dir_inode_operations; 37extern struct inode_operations jfs_dir_inode_operations;
38extern const struct file_operations jfs_dir_operations; 38extern const struct file_operations jfs_dir_operations;
39extern struct inode_operations jfs_file_inode_operations; 39extern struct inode_operations jfs_file_inode_operations;
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
index 7f6e88039700..e1e0a6e6ebdf 100644
--- a/fs/jfs/jfs_metapage.c
+++ b/fs/jfs/jfs_metapage.c
@@ -577,7 +577,7 @@ static void metapage_invalidatepage(struct page *page, unsigned long offset)
577 metapage_releasepage(page, 0); 577 metapage_releasepage(page, 0);
578} 578}
579 579
580struct address_space_operations jfs_metapage_aops = { 580const struct address_space_operations jfs_metapage_aops = {
581 .readpage = metapage_readpage, 581 .readpage = metapage_readpage,
582 .writepage = metapage_writepage, 582 .writepage = metapage_writepage,
583 .sync_page = block_sync_page, 583 .sync_page = block_sync_page,
diff --git a/fs/jfs/jfs_metapage.h b/fs/jfs/jfs_metapage.h
index f0b7d3282b07..d17a3290f5aa 100644
--- a/fs/jfs/jfs_metapage.h
+++ b/fs/jfs/jfs_metapage.h
@@ -139,7 +139,7 @@ static inline void metapage_homeok(struct metapage *mp)
139 put_metapage(mp); 139 put_metapage(mp);
140} 140}
141 141
142extern struct address_space_operations jfs_metapage_aops; 142extern const struct address_space_operations jfs_metapage_aops;
143 143
144/* 144/*
145 * This routines invalidate all pages for an extent. 145 * This routines invalidate all pages for an extent.
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index ac3d66948e8c..10c46231ce15 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -842,7 +842,7 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
842 TXN_UNLOCK(); 842 TXN_UNLOCK();
843 release_metapage(mp); 843 release_metapage(mp);
844 TXN_LOCK(); 844 TXN_LOCK();
845 xtid = tlck->tid; /* reaquire after dropping TXN_LOCK */ 845 xtid = tlck->tid; /* reacquire after dropping TXN_LOCK */
846 846
847 jfs_info("txLock: in waitLock, tid = %d, xtid = %d, lid = %d", 847 jfs_info("txLock: in waitLock, tid = %d, xtid = %d, lid = %d",
848 tid, xtid, lid); 848 tid, xtid, lid);
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 73d2aba084c6..4f6cfebc82db 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -18,7 +18,6 @@
18 */ 18 */
19 19
20#include <linux/fs.h> 20#include <linux/fs.h>
21#include <linux/config.h>
22#include <linux/module.h> 21#include <linux/module.h>
23#include <linux/parser.h> 22#include <linux/parser.h>
24#include <linux/completion.h> 23#include <linux/completion.h>
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index 4db62098d3f4..89ba0df14c22 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -6,7 +6,6 @@
6 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de> 6 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
7 */ 7 */
8 8
9#include <linux/config.h>
10#include <linux/module.h> 9#include <linux/module.h>
11#include <linux/types.h> 10#include <linux/types.h>
12#include <linux/errno.h> 11#include <linux/errno.h>
@@ -455,7 +454,7 @@ static void nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *ho
455 fl->fl_ops = &nlmclnt_lock_ops; 454 fl->fl_ops = &nlmclnt_lock_ops;
456} 455}
457 456
458static void do_vfs_lock(struct file_lock *fl) 457static int do_vfs_lock(struct file_lock *fl)
459{ 458{
460 int res = 0; 459 int res = 0;
461 switch (fl->fl_flags & (FL_POSIX|FL_FLOCK)) { 460 switch (fl->fl_flags & (FL_POSIX|FL_FLOCK)) {
@@ -468,9 +467,7 @@ static void do_vfs_lock(struct file_lock *fl)
468 default: 467 default:
469 BUG(); 468 BUG();
470 } 469 }
471 if (res < 0) 470 return res;
472 printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n",
473 __FUNCTION__);
474} 471}
475 472
476/* 473/*
@@ -499,6 +496,7 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
499 struct nlm_host *host = req->a_host; 496 struct nlm_host *host = req->a_host;
500 struct nlm_res *resp = &req->a_res; 497 struct nlm_res *resp = &req->a_res;
501 struct nlm_wait *block = NULL; 498 struct nlm_wait *block = NULL;
499 unsigned char fl_flags = fl->fl_flags;
502 int status = -ENOLCK; 500 int status = -ENOLCK;
503 501
504 if (!host->h_monitored && nsm_monitor(host) < 0) { 502 if (!host->h_monitored && nsm_monitor(host) < 0) {
@@ -506,6 +504,10 @@ nlmclnt_lock(struct nlm_rqst *req, struct file_lock *fl)
506 host->h_name); 504 host->h_name);
507 goto out; 505 goto out;
508 } 506 }
507 fl->fl_flags |= FL_ACCESS;
508 status = do_vfs_lock(fl);
509 if (status < 0)
510 goto out;
509 511
510 block = nlmclnt_prepare_block(host, fl); 512 block = nlmclnt_prepare_block(host, fl);
511again: 513again:
@@ -540,9 +542,10 @@ again:
540 up_read(&host->h_rwsem); 542 up_read(&host->h_rwsem);
541 goto again; 543 goto again;
542 } 544 }
543 fl->fl_flags |= FL_SLEEP;
544 /* Ensure the resulting lock will get added to granted list */ 545 /* Ensure the resulting lock will get added to granted list */
545 do_vfs_lock(fl); 546 fl->fl_flags = fl_flags | FL_SLEEP;
547 if (do_vfs_lock(fl) < 0)
548 printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __FUNCTION__);
546 up_read(&host->h_rwsem); 549 up_read(&host->h_rwsem);
547 } 550 }
548 status = nlm_stat_to_errno(resp->status); 551 status = nlm_stat_to_errno(resp->status);
@@ -553,6 +556,7 @@ out_unblock:
553 nlmclnt_cancel(host, req->a_args.block, fl); 556 nlmclnt_cancel(host, req->a_args.block, fl);
554out: 557out:
555 nlm_release_call(req); 558 nlm_release_call(req);
559 fl->fl_flags = fl_flags;
556 return status; 560 return status;
557} 561}
558 562
@@ -607,15 +611,19 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl)
607{ 611{
608 struct nlm_host *host = req->a_host; 612 struct nlm_host *host = req->a_host;
609 struct nlm_res *resp = &req->a_res; 613 struct nlm_res *resp = &req->a_res;
610 int status; 614 int status = 0;
611 615
612 /* 616 /*
613 * Note: the server is supposed to either grant us the unlock 617 * Note: the server is supposed to either grant us the unlock
614 * request, or to deny it with NLM_LCK_DENIED_GRACE_PERIOD. In either 618 * request, or to deny it with NLM_LCK_DENIED_GRACE_PERIOD. In either
615 * case, we want to unlock. 619 * case, we want to unlock.
616 */ 620 */
621 fl->fl_flags |= FL_EXISTS;
617 down_read(&host->h_rwsem); 622 down_read(&host->h_rwsem);
618 do_vfs_lock(fl); 623 if (do_vfs_lock(fl) == -ENOENT) {
624 up_read(&host->h_rwsem);
625 goto out;
626 }
619 up_read(&host->h_rwsem); 627 up_read(&host->h_rwsem);
620 628
621 if (req->a_flags & RPC_TASK_ASYNC) 629 if (req->a_flags & RPC_TASK_ASYNC)
@@ -625,7 +633,6 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl)
625 if (status < 0) 633 if (status < 0)
626 goto out; 634 goto out;
627 635
628 status = 0;
629 if (resp->status == NLM_LCK_GRANTED) 636 if (resp->status == NLM_LCK_GRANTED)
630 goto out; 637 goto out;
631 638
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c
index fd56c8872f34..9a991b52c647 100644
--- a/fs/lockd/svc.c
+++ b/fs/lockd/svc.c
@@ -12,7 +12,6 @@
12 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> 12 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
13 */ 13 */
14 14
15#include <linux/config.h>
16#include <linux/module.h> 15#include <linux/module.h>
17#include <linux/init.h> 16#include <linux/init.h>
18#include <linux/sysctl.h> 17#include <linux/sysctl.h>
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index 3ef739120dff..baf5ae513481 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -20,7 +20,6 @@
20 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de> 20 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
21 */ 21 */
22 22
23#include <linux/config.h>
24#include <linux/types.h> 23#include <linux/types.h>
25#include <linux/errno.h> 24#include <linux/errno.h>
26#include <linux/kernel.h> 25#include <linux/kernel.h>
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c
index d210cf304e92..dbb66a3b5cd9 100644
--- a/fs/lockd/svcproc.c
+++ b/fs/lockd/svcproc.c
@@ -7,7 +7,6 @@
7 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de> 7 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
8 */ 8 */
9 9
10#include <linux/config.h>
11#include <linux/types.h> 10#include <linux/types.h>
12#include <linux/time.h> 11#include <linux/time.h>
13#include <linux/slab.h> 12#include <linux/slab.h>
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c
index a570e5c8a930..2a4df9b3779a 100644
--- a/fs/lockd/svcsubs.c
+++ b/fs/lockd/svcsubs.c
@@ -6,7 +6,6 @@
6 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de> 6 * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
7 */ 7 */
8 8
9#include <linux/config.h>
10#include <linux/types.h> 9#include <linux/types.h>
11#include <linux/string.h> 10#include <linux/string.h>
12#include <linux/time.h> 11#include <linux/time.h>
diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c
index f22a3764461a..033ea4ac2c30 100644
--- a/fs/lockd/xdr.c
+++ b/fs/lockd/xdr.c
@@ -6,7 +6,6 @@
6 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> 6 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
7 */ 7 */
8 8
9#include <linux/config.h>
10#include <linux/types.h> 9#include <linux/types.h>
11#include <linux/sched.h> 10#include <linux/sched.h>
12#include <linux/utsname.h> 11#include <linux/utsname.h>
diff --git a/fs/locks.c b/fs/locks.c
index 1ad29c9b6252..b0b41a64e10b 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -725,6 +725,10 @@ next_task:
725/* Try to create a FLOCK lock on filp. We always insert new FLOCK locks 725/* Try to create a FLOCK lock on filp. We always insert new FLOCK locks
726 * at the head of the list, but that's secret knowledge known only to 726 * at the head of the list, but that's secret knowledge known only to
727 * flock_lock_file and posix_lock_file. 727 * flock_lock_file and posix_lock_file.
728 *
729 * Note that if called with an FL_EXISTS argument, the caller may determine
730 * whether or not a lock was successfully freed by testing the return
731 * value for -ENOENT.
728 */ 732 */
729static int flock_lock_file(struct file *filp, struct file_lock *request) 733static int flock_lock_file(struct file *filp, struct file_lock *request)
730{ 734{
@@ -735,6 +739,8 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
735 int found = 0; 739 int found = 0;
736 740
737 lock_kernel(); 741 lock_kernel();
742 if (request->fl_flags & FL_ACCESS)
743 goto find_conflict;
738 for_each_lock(inode, before) { 744 for_each_lock(inode, before) {
739 struct file_lock *fl = *before; 745 struct file_lock *fl = *before;
740 if (IS_POSIX(fl)) 746 if (IS_POSIX(fl))
@@ -750,8 +756,11 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
750 break; 756 break;
751 } 757 }
752 758
753 if (request->fl_type == F_UNLCK) 759 if (request->fl_type == F_UNLCK) {
760 if ((request->fl_flags & FL_EXISTS) && !found)
761 error = -ENOENT;
754 goto out; 762 goto out;
763 }
755 764
756 error = -ENOMEM; 765 error = -ENOMEM;
757 new_fl = locks_alloc_lock(); 766 new_fl = locks_alloc_lock();
@@ -764,6 +773,7 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
764 if (found) 773 if (found)
765 cond_resched(); 774 cond_resched();
766 775
776find_conflict:
767 for_each_lock(inode, before) { 777 for_each_lock(inode, before) {
768 struct file_lock *fl = *before; 778 struct file_lock *fl = *before;
769 if (IS_POSIX(fl)) 779 if (IS_POSIX(fl))
@@ -777,6 +787,8 @@ static int flock_lock_file(struct file *filp, struct file_lock *request)
777 locks_insert_block(fl, request); 787 locks_insert_block(fl, request);
778 goto out; 788 goto out;
779 } 789 }
790 if (request->fl_flags & FL_ACCESS)
791 goto out;
780 locks_copy_lock(new_fl, request); 792 locks_copy_lock(new_fl, request);
781 locks_insert_lock(&inode->i_flock, new_fl); 793 locks_insert_lock(&inode->i_flock, new_fl);
782 new_fl = NULL; 794 new_fl = NULL;
@@ -948,8 +960,11 @@ static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request
948 960
949 error = 0; 961 error = 0;
950 if (!added) { 962 if (!added) {
951 if (request->fl_type == F_UNLCK) 963 if (request->fl_type == F_UNLCK) {
964 if (request->fl_flags & FL_EXISTS)
965 error = -ENOENT;
952 goto out; 966 goto out;
967 }
953 968
954 if (!new_fl) { 969 if (!new_fl) {
955 error = -ENOLCK; 970 error = -ENOLCK;
@@ -996,6 +1011,10 @@ static int __posix_lock_file_conf(struct inode *inode, struct file_lock *request
996 * Add a POSIX style lock to a file. 1011 * Add a POSIX style lock to a file.
997 * We merge adjacent & overlapping locks whenever possible. 1012 * We merge adjacent & overlapping locks whenever possible.
998 * POSIX locks are sorted by owner task, then by starting address 1013 * POSIX locks are sorted by owner task, then by starting address
1014 *
1015 * Note that if called with an FL_EXISTS argument, the caller may determine
1016 * whether or not a lock was successfully freed by testing the return
1017 * value for -ENOENT.
999 */ 1018 */
1000int posix_lock_file(struct file *filp, struct file_lock *fl) 1019int posix_lock_file(struct file *filp, struct file_lock *fl)
1001{ 1020{
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index a6fb509b7341..9ea91c5eeb7b 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -335,7 +335,7 @@ static sector_t minix_bmap(struct address_space *mapping, sector_t block)
335{ 335{
336 return generic_block_bmap(mapping,block,minix_get_block); 336 return generic_block_bmap(mapping,block,minix_get_block);
337} 337}
338static struct address_space_operations minix_aops = { 338static const struct address_space_operations minix_aops = {
339 .readpage = minix_readpage, 339 .readpage = minix_readpage,
340 .writepage = minix_writepage, 340 .writepage = minix_writepage,
341 .sync_page = block_sync_page, 341 .sync_page = block_sync_page,
diff --git a/fs/namei.c b/fs/namei.c
index c784e8bb57a3..c9750d755aff 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1423,7 +1423,7 @@ struct dentry *lock_rename(struct dentry *p1, struct dentry *p2)
1423 struct dentry *p; 1423 struct dentry *p;
1424 1424
1425 if (p1 == p2) { 1425 if (p1 == p2) {
1426 mutex_lock(&p1->d_inode->i_mutex); 1426 mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_PARENT);
1427 return NULL; 1427 return NULL;
1428 } 1428 }
1429 1429
@@ -1431,22 +1431,22 @@ struct dentry *lock_rename(struct dentry *p1, struct dentry *p2)
1431 1431
1432 for (p = p1; p->d_parent != p; p = p->d_parent) { 1432 for (p = p1; p->d_parent != p; p = p->d_parent) {
1433 if (p->d_parent == p2) { 1433 if (p->d_parent == p2) {
1434 mutex_lock(&p2->d_inode->i_mutex); 1434 mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_PARENT);
1435 mutex_lock(&p1->d_inode->i_mutex); 1435 mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_CHILD);
1436 return p; 1436 return p;
1437 } 1437 }
1438 } 1438 }
1439 1439
1440 for (p = p2; p->d_parent != p; p = p->d_parent) { 1440 for (p = p2; p->d_parent != p; p = p->d_parent) {
1441 if (p->d_parent == p1) { 1441 if (p->d_parent == p1) {
1442 mutex_lock(&p1->d_inode->i_mutex); 1442 mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_PARENT);
1443 mutex_lock(&p2->d_inode->i_mutex); 1443 mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_CHILD);
1444 return p; 1444 return p;
1445 } 1445 }
1446 } 1446 }
1447 1447
1448 mutex_lock(&p1->d_inode->i_mutex); 1448 mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_PARENT);
1449 mutex_lock(&p2->d_inode->i_mutex); 1449 mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_CHILD);
1450 return NULL; 1450 return NULL;
1451} 1451}
1452 1452
@@ -1751,7 +1751,7 @@ struct dentry *lookup_create(struct nameidata *nd, int is_dir)
1751{ 1751{
1752 struct dentry *dentry = ERR_PTR(-EEXIST); 1752 struct dentry *dentry = ERR_PTR(-EEXIST);
1753 1753
1754 mutex_lock(&nd->dentry->d_inode->i_mutex); 1754 mutex_lock_nested(&nd->dentry->d_inode->i_mutex, I_MUTEX_PARENT);
1755 /* 1755 /*
1756 * Yucky last component or no last component at all? 1756 * Yucky last component or no last component at all?
1757 * (foo/., foo/.., /////) 1757 * (foo/., foo/.., /////)
@@ -2008,7 +2008,7 @@ static long do_rmdir(int dfd, const char __user *pathname)
2008 error = -EBUSY; 2008 error = -EBUSY;
2009 goto exit1; 2009 goto exit1;
2010 } 2010 }
2011 mutex_lock(&nd.dentry->d_inode->i_mutex); 2011 mutex_lock_nested(&nd.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
2012 dentry = lookup_hash(&nd); 2012 dentry = lookup_hash(&nd);
2013 error = PTR_ERR(dentry); 2013 error = PTR_ERR(dentry);
2014 if (!IS_ERR(dentry)) { 2014 if (!IS_ERR(dentry)) {
@@ -2082,7 +2082,7 @@ static long do_unlinkat(int dfd, const char __user *pathname)
2082 error = -EISDIR; 2082 error = -EISDIR;
2083 if (nd.last_type != LAST_NORM) 2083 if (nd.last_type != LAST_NORM)
2084 goto exit1; 2084 goto exit1;
2085 mutex_lock(&nd.dentry->d_inode->i_mutex); 2085 mutex_lock_nested(&nd.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
2086 dentry = lookup_hash(&nd); 2086 dentry = lookup_hash(&nd);
2087 error = PTR_ERR(dentry); 2087 error = PTR_ERR(dentry);
2088 if (!IS_ERR(dentry)) { 2088 if (!IS_ERR(dentry)) {
diff --git a/fs/namespace.c b/fs/namespace.c
index b3ed212ea416..fa7ed6a9fc2d 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -8,7 +8,6 @@
8 * Heavily rewritten. 8 * Heavily rewritten.
9 */ 9 */
10 10
11#include <linux/config.h>
12#include <linux/syscalls.h> 11#include <linux/syscalls.h>
13#include <linux/slab.h> 12#include <linux/slab.h>
14#include <linux/sched.h> 13#include <linux/sched.h>
diff --git a/fs/ncpfs/dir.c b/fs/ncpfs/dir.c
index f0860c602d8b..b4ee89250e95 100644
--- a/fs/ncpfs/dir.c
+++ b/fs/ncpfs/dir.c
@@ -10,7 +10,6 @@
10 * 10 *
11 */ 11 */
12 12
13#include <linux/config.h>
14 13
15#include <linux/time.h> 14#include <linux/time.h>
16#include <linux/errno.h> 15#include <linux/errno.h>
diff --git a/fs/ncpfs/inode.c b/fs/ncpfs/inode.c
index 90d2ea28f333..1ddf77b0b825 100644
--- a/fs/ncpfs/inode.c
+++ b/fs/ncpfs/inode.c
@@ -9,7 +9,6 @@
9 * 9 *
10 */ 10 */
11 11
12#include <linux/config.h>
13#include <linux/module.h> 12#include <linux/module.h>
14 13
15#include <asm/system.h> 14#include <asm/system.h>
@@ -105,7 +104,7 @@ static struct super_operations ncp_sops =
105 104
106extern struct dentry_operations ncp_root_dentry_operations; 105extern struct dentry_operations ncp_root_dentry_operations;
107#if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS) 106#if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
108extern struct address_space_operations ncp_symlink_aops; 107extern const struct address_space_operations ncp_symlink_aops;
109extern int ncp_symlink(struct inode*, struct dentry*, const char*); 108extern int ncp_symlink(struct inode*, struct dentry*, const char*);
110#endif 109#endif
111 110
diff --git a/fs/ncpfs/ioctl.c b/fs/ncpfs/ioctl.c
index eb3813ad136f..42039fe0653c 100644
--- a/fs/ncpfs/ioctl.c
+++ b/fs/ncpfs/ioctl.c
@@ -7,7 +7,6 @@
7 * 7 *
8 */ 8 */
9 9
10#include <linux/config.h>
11 10
12#include <asm/uaccess.h> 11#include <asm/uaccess.h>
13#include <linux/capability.h> 12#include <linux/capability.h>
diff --git a/fs/ncpfs/mmap.c b/fs/ncpfs/mmap.c
index 52d60c3d8996..e7d5a3097fe6 100644
--- a/fs/ncpfs/mmap.c
+++ b/fs/ncpfs/mmap.c
@@ -93,7 +93,7 @@ static struct page* ncp_file_mmap_nopage(struct vm_area_struct *area,
93 */ 93 */
94 if (type) 94 if (type)
95 *type = VM_FAULT_MAJOR; 95 *type = VM_FAULT_MAJOR;
96 inc_page_state(pgmajfault); 96 count_vm_event(PGMAJFAULT);
97 return page; 97 return page;
98} 98}
99 99
diff --git a/fs/ncpfs/ncplib_kernel.c b/fs/ncpfs/ncplib_kernel.c
index d9ebf6439f59..551e0bac7aac 100644
--- a/fs/ncpfs/ncplib_kernel.c
+++ b/fs/ncpfs/ncplib_kernel.c
@@ -10,7 +10,6 @@
10 */ 10 */
11 11
12 12
13#include <linux/config.h>
14 13
15#include "ncplib_kernel.h" 14#include "ncplib_kernel.h"
16 15
diff --git a/fs/ncpfs/ncplib_kernel.h b/fs/ncpfs/ncplib_kernel.h
index 799e5c2bec55..2441d1ab57dc 100644
--- a/fs/ncpfs/ncplib_kernel.h
+++ b/fs/ncpfs/ncplib_kernel.h
@@ -12,7 +12,6 @@
12#ifndef _NCPLIB_H 12#ifndef _NCPLIB_H
13#define _NCPLIB_H 13#define _NCPLIB_H
14 14
15#include <linux/config.h>
16 15
17#include <linux/fs.h> 16#include <linux/fs.h>
18#include <linux/types.h> 17#include <linux/types.h>
diff --git a/fs/ncpfs/ncpsign_kernel.c b/fs/ncpfs/ncpsign_kernel.c
index a6ec90cd8894..749a18d33599 100644
--- a/fs/ncpfs/ncpsign_kernel.c
+++ b/fs/ncpfs/ncpsign_kernel.c
@@ -5,7 +5,6 @@
5 * 5 *
6 */ 6 */
7 7
8#include <linux/config.h>
9 8
10#ifdef CONFIG_NCPFS_PACKET_SIGNING 9#ifdef CONFIG_NCPFS_PACKET_SIGNING
11 10
diff --git a/fs/ncpfs/sock.c b/fs/ncpfs/sock.c
index 8783eb7ec641..11c2b252ebed 100644
--- a/fs/ncpfs/sock.c
+++ b/fs/ncpfs/sock.c
@@ -8,7 +8,6 @@
8 * 8 *
9 */ 9 */
10 10
11#include <linux/config.h>
12 11
13#include <linux/time.h> 12#include <linux/time.h>
14#include <linux/errno.h> 13#include <linux/errno.h>
diff --git a/fs/ncpfs/symlink.c b/fs/ncpfs/symlink.c
index e935f1b34bc2..ca92c2406635 100644
--- a/fs/ncpfs/symlink.c
+++ b/fs/ncpfs/symlink.c
@@ -20,7 +20,6 @@
20 * 20 *
21 */ 21 */
22 22
23#include <linux/config.h>
24 23
25#include <asm/uaccess.h> 24#include <asm/uaccess.h>
26 25
@@ -99,7 +98,7 @@ fail:
99/* 98/*
100 * symlinks can't do much... 99 * symlinks can't do much...
101 */ 100 */
102struct address_space_operations ncp_symlink_aops = { 101const struct address_space_operations ncp_symlink_aops = {
103 .readpage = ncp_symlink_readpage, 102 .readpage = ncp_symlink_readpage,
104}; 103};
105 104
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index d53f8c6a9ecb..fe0a6b8ac149 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -6,7 +6,6 @@
6 * NFSv4 callback handling 6 * NFSv4 callback handling
7 */ 7 */
8 8
9#include <linux/config.h>
10#include <linux/completion.h> 9#include <linux/completion.h>
11#include <linux/ip.h> 10#include <linux/ip.h>
12#include <linux/module.h> 11#include <linux/module.h>
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c
index 462cfceb50c5..7719483ecdfc 100644
--- a/fs/nfs/callback_proc.c
+++ b/fs/nfs/callback_proc.c
@@ -5,7 +5,6 @@
5 * 5 *
6 * NFSv4 callback procedures 6 * NFSv4 callback procedures
7 */ 7 */
8#include <linux/config.h>
9#include <linux/nfs4.h> 8#include <linux/nfs4.h>
10#include <linux/nfs_fs.h> 9#include <linux/nfs_fs.h>
11#include "nfs4_fs.h" 10#include "nfs4_fs.h"
diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c
index c92991328d9a..29f932192054 100644
--- a/fs/nfs/callback_xdr.c
+++ b/fs/nfs/callback_xdr.c
@@ -5,7 +5,6 @@
5 * 5 *
6 * NFSv4 callback encode/decode procedures 6 * NFSv4 callback encode/decode procedures
7 */ 7 */
8#include <linux/config.h>
9#include <linux/kernel.h> 8#include <linux/kernel.h>
10#include <linux/sunrpc/svc.h> 9#include <linux/sunrpc/svc.h>
11#include <linux/nfs4.h> 10#include <linux/nfs4.h>
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index d3be923d4e43..9540a316c05e 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -6,7 +6,6 @@
6 * NFS file delegation management 6 * NFS file delegation management
7 * 7 *
8 */ 8 */
9#include <linux/config.h>
10#include <linux/completion.h> 9#include <linux/completion.h>
11#include <linux/kthread.h> 10#include <linux/kthread.h>
12#include <linux/module.h> 11#include <linux/module.h>
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 3ddda6f7ecc2..e7ffb4deb3e5 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -690,7 +690,9 @@ int nfs_lookup_verify_inode(struct inode *inode, struct nameidata *nd)
690 goto out_force; 690 goto out_force;
691 /* This is an open(2) */ 691 /* This is an open(2) */
692 if (nfs_lookup_check_intent(nd, LOOKUP_OPEN) != 0 && 692 if (nfs_lookup_check_intent(nd, LOOKUP_OPEN) != 0 &&
693 !(server->flags & NFS_MOUNT_NOCTO)) 693 !(server->flags & NFS_MOUNT_NOCTO) &&
694 (S_ISREG(inode->i_mode) ||
695 S_ISDIR(inode->i_mode)))
694 goto out_force; 696 goto out_force;
695 } 697 }
696 return nfs_revalidate_inode(server, inode); 698 return nfs_revalidate_inode(server, inode);
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 8ca9707be6c9..fecd3b095deb 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -38,7 +38,6 @@
38 * 38 *
39 */ 39 */
40 40
41#include <linux/config.h>
42#include <linux/errno.h> 41#include <linux/errno.h>
43#include <linux/sched.h> 42#include <linux/sched.h>
44#include <linux/kernel.h> 43#include <linux/kernel.h>
@@ -68,25 +67,19 @@ struct nfs_direct_req {
68 struct kref kref; /* release manager */ 67 struct kref kref; /* release manager */
69 68
70 /* I/O parameters */ 69 /* I/O parameters */
71 struct list_head list, /* nfs_read/write_data structs */
72 rewrite_list; /* saved nfs_write_data structs */
73 struct nfs_open_context *ctx; /* file open context info */ 70 struct nfs_open_context *ctx; /* file open context info */
74 struct kiocb * iocb; /* controlling i/o request */ 71 struct kiocb * iocb; /* controlling i/o request */
75 struct inode * inode; /* target file of i/o */ 72 struct inode * inode; /* target file of i/o */
76 unsigned long user_addr; /* location of user's buffer */
77 size_t user_count; /* total bytes to move */
78 loff_t pos; /* starting offset in file */
79 struct page ** pages; /* pages in our buffer */
80 unsigned int npages; /* count of pages */
81 73
82 /* completion state */ 74 /* completion state */
75 atomic_t io_count; /* i/os we're waiting for */
83 spinlock_t lock; /* protect completion state */ 76 spinlock_t lock; /* protect completion state */
84 int outstanding; /* i/os we're waiting for */
85 ssize_t count, /* bytes actually processed */ 77 ssize_t count, /* bytes actually processed */
86 error; /* any reported error */ 78 error; /* any reported error */
87 struct completion completion; /* wait for i/o completion */ 79 struct completion completion; /* wait for i/o completion */
88 80
89 /* commit state */ 81 /* commit state */
82 struct list_head rewrite_list; /* saved nfs_write_data structs */
90 struct nfs_write_data * commit_data; /* special write_data for commits */ 83 struct nfs_write_data * commit_data; /* special write_data for commits */
91 int flags; 84 int flags;
92#define NFS_ODIRECT_DO_COMMIT (1) /* an unstable reply was received */ 85#define NFS_ODIRECT_DO_COMMIT (1) /* an unstable reply was received */
@@ -94,8 +87,37 @@ struct nfs_direct_req {
94 struct nfs_writeverf verf; /* unstable write verifier */ 87 struct nfs_writeverf verf; /* unstable write verifier */
95}; 88};
96 89
97static void nfs_direct_write_schedule(struct nfs_direct_req *dreq, int sync);
98static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode *inode); 90static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode *inode);
91static const struct rpc_call_ops nfs_write_direct_ops;
92
93static inline void get_dreq(struct nfs_direct_req *dreq)
94{
95 atomic_inc(&dreq->io_count);
96}
97
98static inline int put_dreq(struct nfs_direct_req *dreq)
99{
100 return atomic_dec_and_test(&dreq->io_count);
101}
102
103/*
104 * "size" is never larger than rsize or wsize.
105 */
106static inline int nfs_direct_count_pages(unsigned long user_addr, size_t size)
107{
108 int page_count;
109
110 page_count = (user_addr + size + PAGE_SIZE - 1) >> PAGE_SHIFT;
111 page_count -= user_addr >> PAGE_SHIFT;
112 BUG_ON(page_count < 0);
113
114 return page_count;
115}
116
117static inline unsigned int nfs_max_pages(unsigned int size)
118{
119 return (size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
120}
99 121
100/** 122/**
101 * nfs_direct_IO - NFS address space operation for direct I/O 123 * nfs_direct_IO - NFS address space operation for direct I/O
@@ -119,50 +141,21 @@ ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, loff_
119 return -EINVAL; 141 return -EINVAL;
120} 142}
121 143
122static void nfs_free_user_pages(struct page **pages, int npages, int do_dirty) 144static void nfs_direct_dirty_pages(struct page **pages, int npages)
123{ 145{
124 int i; 146 int i;
125 for (i = 0; i < npages; i++) { 147 for (i = 0; i < npages; i++) {
126 struct page *page = pages[i]; 148 struct page *page = pages[i];
127 if (do_dirty && !PageCompound(page)) 149 if (!PageCompound(page))
128 set_page_dirty_lock(page); 150 set_page_dirty_lock(page);
129 page_cache_release(page);
130 } 151 }
131 kfree(pages);
132} 152}
133 153
134static inline int nfs_get_user_pages(int rw, unsigned long user_addr, size_t size, struct page ***pages) 154static void nfs_direct_release_pages(struct page **pages, int npages)
135{ 155{
136 int result = -ENOMEM; 156 int i;
137 unsigned long page_count; 157 for (i = 0; i < npages; i++)
138 size_t array_size; 158 page_cache_release(pages[i]);
139
140 page_count = (user_addr + size + PAGE_SIZE - 1) >> PAGE_SHIFT;
141 page_count -= user_addr >> PAGE_SHIFT;
142
143 array_size = (page_count * sizeof(struct page *));
144 *pages = kmalloc(array_size, GFP_KERNEL);
145 if (*pages) {
146 down_read(&current->mm->mmap_sem);
147 result = get_user_pages(current, current->mm, user_addr,
148 page_count, (rw == READ), 0,
149 *pages, NULL);
150 up_read(&current->mm->mmap_sem);
151 if (result != page_count) {
152 /*
153 * If we got fewer pages than expected from
154 * get_user_pages(), the user buffer runs off the
155 * end of a mapping; return EFAULT.
156 */
157 if (result >= 0) {
158 nfs_free_user_pages(*pages, result, 0);
159 result = -EFAULT;
160 } else
161 kfree(*pages);
162 *pages = NULL;
163 }
164 }
165 return result;
166} 159}
167 160
168static inline struct nfs_direct_req *nfs_direct_req_alloc(void) 161static inline struct nfs_direct_req *nfs_direct_req_alloc(void)
@@ -174,13 +167,13 @@ static inline struct nfs_direct_req *nfs_direct_req_alloc(void)
174 return NULL; 167 return NULL;
175 168
176 kref_init(&dreq->kref); 169 kref_init(&dreq->kref);
170 kref_get(&dreq->kref);
177 init_completion(&dreq->completion); 171 init_completion(&dreq->completion);
178 INIT_LIST_HEAD(&dreq->list);
179 INIT_LIST_HEAD(&dreq->rewrite_list); 172 INIT_LIST_HEAD(&dreq->rewrite_list);
180 dreq->iocb = NULL; 173 dreq->iocb = NULL;
181 dreq->ctx = NULL; 174 dreq->ctx = NULL;
182 spin_lock_init(&dreq->lock); 175 spin_lock_init(&dreq->lock);
183 dreq->outstanding = 0; 176 atomic_set(&dreq->io_count, 0);
184 dreq->count = 0; 177 dreq->count = 0;
185 dreq->error = 0; 178 dreq->error = 0;
186 dreq->flags = 0; 179 dreq->flags = 0;
@@ -221,18 +214,11 @@ out:
221} 214}
222 215
223/* 216/*
224 * We must hold a reference to all the pages in this direct read request 217 * Synchronous I/O uses a stack-allocated iocb. Thus we can't trust
225 * until the RPCs complete. This could be long *after* we are woken up in 218 * the iocb is still valid here if this is a synchronous request.
226 * nfs_direct_wait (for instance, if someone hits ^C on a slow server).
227 *
228 * In addition, synchronous I/O uses a stack-allocated iocb. Thus we
229 * can't trust the iocb is still valid here if this is a synchronous
230 * request. If the waiter is woken prematurely, the iocb is long gone.
231 */ 219 */
232static void nfs_direct_complete(struct nfs_direct_req *dreq) 220static void nfs_direct_complete(struct nfs_direct_req *dreq)
233{ 221{
234 nfs_free_user_pages(dreq->pages, dreq->npages, 1);
235
236 if (dreq->iocb) { 222 if (dreq->iocb) {
237 long res = (long) dreq->error; 223 long res = (long) dreq->error;
238 if (!res) 224 if (!res)
@@ -245,48 +231,10 @@ static void nfs_direct_complete(struct nfs_direct_req *dreq)
245} 231}
246 232
247/* 233/*
248 * Note we also set the number of requests we have in the dreq when we are 234 * We must hold a reference to all the pages in this direct read request
249 * done. This prevents races with I/O completion so we will always wait 235 * until the RPCs complete. This could be long *after* we are woken up in
250 * until all requests have been dispatched and completed. 236 * nfs_direct_wait (for instance, if someone hits ^C on a slow server).
251 */ 237 */
252static struct nfs_direct_req *nfs_direct_read_alloc(size_t nbytes, size_t rsize)
253{
254 struct list_head *list;
255 struct nfs_direct_req *dreq;
256 unsigned int rpages = (rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
257
258 dreq = nfs_direct_req_alloc();
259 if (!dreq)
260 return NULL;
261
262 list = &dreq->list;
263 for(;;) {
264 struct nfs_read_data *data = nfs_readdata_alloc(rpages);
265
266 if (unlikely(!data)) {
267 while (!list_empty(list)) {
268 data = list_entry(list->next,
269 struct nfs_read_data, pages);
270 list_del(&data->pages);
271 nfs_readdata_free(data);
272 }
273 kref_put(&dreq->kref, nfs_direct_req_release);
274 return NULL;
275 }
276
277 INIT_LIST_HEAD(&data->pages);
278 list_add(&data->pages, list);
279
280 data->req = (struct nfs_page *) dreq;
281 dreq->outstanding++;
282 if (nbytes <= rsize)
283 break;
284 nbytes -= rsize;
285 }
286 kref_get(&dreq->kref);
287 return dreq;
288}
289
290static void nfs_direct_read_result(struct rpc_task *task, void *calldata) 238static void nfs_direct_read_result(struct rpc_task *task, void *calldata)
291{ 239{
292 struct nfs_read_data *data = calldata; 240 struct nfs_read_data *data = calldata;
@@ -295,6 +243,9 @@ static void nfs_direct_read_result(struct rpc_task *task, void *calldata)
295 if (nfs_readpage_result(task, data) != 0) 243 if (nfs_readpage_result(task, data) != 0)
296 return; 244 return;
297 245
246 nfs_direct_dirty_pages(data->pagevec, data->npages);
247 nfs_direct_release_pages(data->pagevec, data->npages);
248
298 spin_lock(&dreq->lock); 249 spin_lock(&dreq->lock);
299 250
300 if (likely(task->tk_status >= 0)) 251 if (likely(task->tk_status >= 0))
@@ -302,13 +253,10 @@ static void nfs_direct_read_result(struct rpc_task *task, void *calldata)
302 else 253 else
303 dreq->error = task->tk_status; 254 dreq->error = task->tk_status;
304 255
305 if (--dreq->outstanding) {
306 spin_unlock(&dreq->lock);
307 return;
308 }
309
310 spin_unlock(&dreq->lock); 256 spin_unlock(&dreq->lock);
311 nfs_direct_complete(dreq); 257
258 if (put_dreq(dreq))
259 nfs_direct_complete(dreq);
312} 260}
313 261
314static const struct rpc_call_ops nfs_read_direct_ops = { 262static const struct rpc_call_ops nfs_read_direct_ops = {
@@ -317,41 +265,60 @@ static const struct rpc_call_ops nfs_read_direct_ops = {
317}; 265};
318 266
319/* 267/*
320 * For each nfs_read_data struct that was allocated on the list, dispatch 268 * For each rsize'd chunk of the user's buffer, dispatch an NFS READ
321 * an NFS READ operation 269 * operation. If nfs_readdata_alloc() or get_user_pages() fails,
270 * bail and stop sending more reads. Read length accounting is
271 * handled automatically by nfs_direct_read_result(). Otherwise, if
272 * no requests have been sent, just return an error.
322 */ 273 */
323static void nfs_direct_read_schedule(struct nfs_direct_req *dreq) 274static ssize_t nfs_direct_read_schedule(struct nfs_direct_req *dreq, unsigned long user_addr, size_t count, loff_t pos)
324{ 275{
325 struct nfs_open_context *ctx = dreq->ctx; 276 struct nfs_open_context *ctx = dreq->ctx;
326 struct inode *inode = ctx->dentry->d_inode; 277 struct inode *inode = ctx->dentry->d_inode;
327 struct list_head *list = &dreq->list;
328 struct page **pages = dreq->pages;
329 size_t count = dreq->user_count;
330 loff_t pos = dreq->pos;
331 size_t rsize = NFS_SERVER(inode)->rsize; 278 size_t rsize = NFS_SERVER(inode)->rsize;
332 unsigned int curpage, pgbase; 279 unsigned int rpages = nfs_max_pages(rsize);
280 unsigned int pgbase;
281 int result;
282 ssize_t started = 0;
283
284 get_dreq(dreq);
333 285
334 curpage = 0; 286 pgbase = user_addr & ~PAGE_MASK;
335 pgbase = dreq->user_addr & ~PAGE_MASK;
336 do { 287 do {
337 struct nfs_read_data *data; 288 struct nfs_read_data *data;
338 size_t bytes; 289 size_t bytes;
339 290
291 result = -ENOMEM;
292 data = nfs_readdata_alloc(rpages);
293 if (unlikely(!data))
294 break;
295
340 bytes = rsize; 296 bytes = rsize;
341 if (count < rsize) 297 if (count < rsize)
342 bytes = count; 298 bytes = count;
343 299
344 BUG_ON(list_empty(list)); 300 data->npages = nfs_direct_count_pages(user_addr, bytes);
345 data = list_entry(list->next, struct nfs_read_data, pages); 301 down_read(&current->mm->mmap_sem);
346 list_del_init(&data->pages); 302 result = get_user_pages(current, current->mm, user_addr,
303 data->npages, 1, 0, data->pagevec, NULL);
304 up_read(&current->mm->mmap_sem);
305 if (unlikely(result < data->npages)) {
306 if (result > 0)
307 nfs_direct_release_pages(data->pagevec, result);
308 nfs_readdata_release(data);
309 break;
310 }
311
312 get_dreq(dreq);
347 313
314 data->req = (struct nfs_page *) dreq;
348 data->inode = inode; 315 data->inode = inode;
349 data->cred = ctx->cred; 316 data->cred = ctx->cred;
350 data->args.fh = NFS_FH(inode); 317 data->args.fh = NFS_FH(inode);
351 data->args.context = ctx; 318 data->args.context = ctx;
352 data->args.offset = pos; 319 data->args.offset = pos;
353 data->args.pgbase = pgbase; 320 data->args.pgbase = pgbase;
354 data->args.pages = &pages[curpage]; 321 data->args.pages = data->pagevec;
355 data->args.count = bytes; 322 data->args.count = bytes;
356 data->res.fattr = &data->fattr; 323 data->res.fattr = &data->fattr;
357 data->res.eof = 0; 324 data->res.eof = 0;
@@ -374,33 +341,35 @@ static void nfs_direct_read_schedule(struct nfs_direct_req *dreq)
374 bytes, 341 bytes,
375 (unsigned long long)data->args.offset); 342 (unsigned long long)data->args.offset);
376 343
344 started += bytes;
345 user_addr += bytes;
377 pos += bytes; 346 pos += bytes;
378 pgbase += bytes; 347 pgbase += bytes;
379 curpage += pgbase >> PAGE_SHIFT;
380 pgbase &= ~PAGE_MASK; 348 pgbase &= ~PAGE_MASK;
381 349
382 count -= bytes; 350 count -= bytes;
383 } while (count != 0); 351 } while (count != 0);
384 BUG_ON(!list_empty(list)); 352
353 if (put_dreq(dreq))
354 nfs_direct_complete(dreq);
355
356 if (started)
357 return 0;
358 return result < 0 ? (ssize_t) result : -EFAULT;
385} 359}
386 360
387static ssize_t nfs_direct_read(struct kiocb *iocb, unsigned long user_addr, size_t count, loff_t pos, struct page **pages, unsigned int nr_pages) 361static ssize_t nfs_direct_read(struct kiocb *iocb, unsigned long user_addr, size_t count, loff_t pos)
388{ 362{
389 ssize_t result; 363 ssize_t result = 0;
390 sigset_t oldset; 364 sigset_t oldset;
391 struct inode *inode = iocb->ki_filp->f_mapping->host; 365 struct inode *inode = iocb->ki_filp->f_mapping->host;
392 struct rpc_clnt *clnt = NFS_CLIENT(inode); 366 struct rpc_clnt *clnt = NFS_CLIENT(inode);
393 struct nfs_direct_req *dreq; 367 struct nfs_direct_req *dreq;
394 368
395 dreq = nfs_direct_read_alloc(count, NFS_SERVER(inode)->rsize); 369 dreq = nfs_direct_req_alloc();
396 if (!dreq) 370 if (!dreq)
397 return -ENOMEM; 371 return -ENOMEM;
398 372
399 dreq->user_addr = user_addr;
400 dreq->user_count = count;
401 dreq->pos = pos;
402 dreq->pages = pages;
403 dreq->npages = nr_pages;
404 dreq->inode = inode; 373 dreq->inode = inode;
405 dreq->ctx = get_nfs_open_context((struct nfs_open_context *)iocb->ki_filp->private_data); 374 dreq->ctx = get_nfs_open_context((struct nfs_open_context *)iocb->ki_filp->private_data);
406 if (!is_sync_kiocb(iocb)) 375 if (!is_sync_kiocb(iocb))
@@ -408,8 +377,9 @@ static ssize_t nfs_direct_read(struct kiocb *iocb, unsigned long user_addr, size
408 377
409 nfs_add_stats(inode, NFSIOS_DIRECTREADBYTES, count); 378 nfs_add_stats(inode, NFSIOS_DIRECTREADBYTES, count);
410 rpc_clnt_sigmask(clnt, &oldset); 379 rpc_clnt_sigmask(clnt, &oldset);
411 nfs_direct_read_schedule(dreq); 380 result = nfs_direct_read_schedule(dreq, user_addr, count, pos);
412 result = nfs_direct_wait(dreq); 381 if (!result)
382 result = nfs_direct_wait(dreq);
413 rpc_clnt_sigunmask(clnt, &oldset); 383 rpc_clnt_sigunmask(clnt, &oldset);
414 384
415 return result; 385 return result;
@@ -417,10 +387,10 @@ static ssize_t nfs_direct_read(struct kiocb *iocb, unsigned long user_addr, size
417 387
418static void nfs_direct_free_writedata(struct nfs_direct_req *dreq) 388static void nfs_direct_free_writedata(struct nfs_direct_req *dreq)
419{ 389{
420 list_splice_init(&dreq->rewrite_list, &dreq->list); 390 while (!list_empty(&dreq->rewrite_list)) {
421 while (!list_empty(&dreq->list)) { 391 struct nfs_write_data *data = list_entry(dreq->rewrite_list.next, struct nfs_write_data, pages);
422 struct nfs_write_data *data = list_entry(dreq->list.next, struct nfs_write_data, pages);
423 list_del(&data->pages); 392 list_del(&data->pages);
393 nfs_direct_release_pages(data->pagevec, data->npages);
424 nfs_writedata_release(data); 394 nfs_writedata_release(data);
425 } 395 }
426} 396}
@@ -428,14 +398,51 @@ static void nfs_direct_free_writedata(struct nfs_direct_req *dreq)
428#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) 398#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
429static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) 399static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
430{ 400{
431 struct list_head *pos; 401 struct inode *inode = dreq->inode;
402 struct list_head *p;
403 struct nfs_write_data *data;
432 404
433 list_splice_init(&dreq->rewrite_list, &dreq->list);
434 list_for_each(pos, &dreq->list)
435 dreq->outstanding++;
436 dreq->count = 0; 405 dreq->count = 0;
406 get_dreq(dreq);
407
408 list_for_each(p, &dreq->rewrite_list) {
409 data = list_entry(p, struct nfs_write_data, pages);
410
411 get_dreq(dreq);
412
413 /*
414 * Reset data->res.
415 */
416 nfs_fattr_init(&data->fattr);
417 data->res.count = data->args.count;
418 memset(&data->verf, 0, sizeof(data->verf));
419
420 /*
421 * Reuse data->task; data->args should not have changed
422 * since the original request was sent.
423 */
424 rpc_init_task(&data->task, NFS_CLIENT(inode), RPC_TASK_ASYNC,
425 &nfs_write_direct_ops, data);
426 NFS_PROTO(inode)->write_setup(data, FLUSH_STABLE);
427
428 data->task.tk_priority = RPC_PRIORITY_NORMAL;
429 data->task.tk_cookie = (unsigned long) inode;
430
431 /*
432 * We're called via an RPC callback, so BKL is already held.
433 */
434 rpc_execute(&data->task);
435
436 dprintk("NFS: %5u rescheduled direct write call (req %s/%Ld, %u bytes @ offset %Lu)\n",
437 data->task.tk_pid,
438 inode->i_sb->s_id,
439 (long long)NFS_FILEID(inode),
440 data->args.count,
441 (unsigned long long)data->args.offset);
442 }
437 443
438 nfs_direct_write_schedule(dreq, FLUSH_STABLE); 444 if (put_dreq(dreq))
445 nfs_direct_write_complete(dreq, inode);
439} 446}
440 447
441static void nfs_direct_commit_result(struct rpc_task *task, void *calldata) 448static void nfs_direct_commit_result(struct rpc_task *task, void *calldata)
@@ -472,8 +479,8 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
472 data->cred = dreq->ctx->cred; 479 data->cred = dreq->ctx->cred;
473 480
474 data->args.fh = NFS_FH(data->inode); 481 data->args.fh = NFS_FH(data->inode);
475 data->args.offset = dreq->pos; 482 data->args.offset = 0;
476 data->args.count = dreq->user_count; 483 data->args.count = 0;
477 data->res.count = 0; 484 data->res.count = 0;
478 data->res.fattr = &data->fattr; 485 data->res.fattr = &data->fattr;
479 data->res.verf = &data->verf; 486 data->res.verf = &data->verf;
@@ -535,47 +542,6 @@ static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode
535} 542}
536#endif 543#endif
537 544
538static struct nfs_direct_req *nfs_direct_write_alloc(size_t nbytes, size_t wsize)
539{
540 struct list_head *list;
541 struct nfs_direct_req *dreq;
542 unsigned int wpages = (wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
543
544 dreq = nfs_direct_req_alloc();
545 if (!dreq)
546 return NULL;
547
548 list = &dreq->list;
549 for(;;) {
550 struct nfs_write_data *data = nfs_writedata_alloc(wpages);
551
552 if (unlikely(!data)) {
553 while (!list_empty(list)) {
554 data = list_entry(list->next,
555 struct nfs_write_data, pages);
556 list_del(&data->pages);
557 nfs_writedata_free(data);
558 }
559 kref_put(&dreq->kref, nfs_direct_req_release);
560 return NULL;
561 }
562
563 INIT_LIST_HEAD(&data->pages);
564 list_add(&data->pages, list);
565
566 data->req = (struct nfs_page *) dreq;
567 dreq->outstanding++;
568 if (nbytes <= wsize)
569 break;
570 nbytes -= wsize;
571 }
572
573 nfs_alloc_commit_data(dreq);
574
575 kref_get(&dreq->kref);
576 return dreq;
577}
578
579static void nfs_direct_write_result(struct rpc_task *task, void *calldata) 545static void nfs_direct_write_result(struct rpc_task *task, void *calldata)
580{ 546{
581 struct nfs_write_data *data = calldata; 547 struct nfs_write_data *data = calldata;
@@ -605,8 +571,6 @@ static void nfs_direct_write_result(struct rpc_task *task, void *calldata)
605 } 571 }
606 } 572 }
607 } 573 }
608 /* In case we have to resend */
609 data->args.stable = NFS_FILE_SYNC;
610 574
611 spin_unlock(&dreq->lock); 575 spin_unlock(&dreq->lock);
612} 576}
@@ -620,14 +584,8 @@ static void nfs_direct_write_release(void *calldata)
620 struct nfs_write_data *data = calldata; 584 struct nfs_write_data *data = calldata;
621 struct nfs_direct_req *dreq = (struct nfs_direct_req *) data->req; 585 struct nfs_direct_req *dreq = (struct nfs_direct_req *) data->req;
622 586
623 spin_lock(&dreq->lock); 587 if (put_dreq(dreq))
624 if (--dreq->outstanding) { 588 nfs_direct_write_complete(dreq, data->inode);
625 spin_unlock(&dreq->lock);
626 return;
627 }
628 spin_unlock(&dreq->lock);
629
630 nfs_direct_write_complete(dreq, data->inode);
631} 589}
632 590
633static const struct rpc_call_ops nfs_write_direct_ops = { 591static const struct rpc_call_ops nfs_write_direct_ops = {
@@ -636,41 +594,62 @@ static const struct rpc_call_ops nfs_write_direct_ops = {
636}; 594};
637 595
638/* 596/*
639 * For each nfs_write_data struct that was allocated on the list, dispatch 597 * For each wsize'd chunk of the user's buffer, dispatch an NFS WRITE
640 * an NFS WRITE operation 598 * operation. If nfs_writedata_alloc() or get_user_pages() fails,
599 * bail and stop sending more writes. Write length accounting is
600 * handled automatically by nfs_direct_write_result(). Otherwise, if
601 * no requests have been sent, just return an error.
641 */ 602 */
642static void nfs_direct_write_schedule(struct nfs_direct_req *dreq, int sync) 603static ssize_t nfs_direct_write_schedule(struct nfs_direct_req *dreq, unsigned long user_addr, size_t count, loff_t pos, int sync)
643{ 604{
644 struct nfs_open_context *ctx = dreq->ctx; 605 struct nfs_open_context *ctx = dreq->ctx;
645 struct inode *inode = ctx->dentry->d_inode; 606 struct inode *inode = ctx->dentry->d_inode;
646 struct list_head *list = &dreq->list;
647 struct page **pages = dreq->pages;
648 size_t count = dreq->user_count;
649 loff_t pos = dreq->pos;
650 size_t wsize = NFS_SERVER(inode)->wsize; 607 size_t wsize = NFS_SERVER(inode)->wsize;
651 unsigned int curpage, pgbase; 608 unsigned int wpages = nfs_max_pages(wsize);
609 unsigned int pgbase;
610 int result;
611 ssize_t started = 0;
652 612
653 curpage = 0; 613 get_dreq(dreq);
654 pgbase = dreq->user_addr & ~PAGE_MASK; 614
615 pgbase = user_addr & ~PAGE_MASK;
655 do { 616 do {
656 struct nfs_write_data *data; 617 struct nfs_write_data *data;
657 size_t bytes; 618 size_t bytes;
658 619
620 result = -ENOMEM;
621 data = nfs_writedata_alloc(wpages);
622 if (unlikely(!data))
623 break;
624
659 bytes = wsize; 625 bytes = wsize;
660 if (count < wsize) 626 if (count < wsize)
661 bytes = count; 627 bytes = count;
662 628
663 BUG_ON(list_empty(list)); 629 data->npages = nfs_direct_count_pages(user_addr, bytes);
664 data = list_entry(list->next, struct nfs_write_data, pages); 630 down_read(&current->mm->mmap_sem);
631 result = get_user_pages(current, current->mm, user_addr,
632 data->npages, 0, 0, data->pagevec, NULL);
633 up_read(&current->mm->mmap_sem);
634 if (unlikely(result < data->npages)) {
635 if (result > 0)
636 nfs_direct_release_pages(data->pagevec, result);
637 nfs_writedata_release(data);
638 break;
639 }
640
641 get_dreq(dreq);
642
665 list_move_tail(&data->pages, &dreq->rewrite_list); 643 list_move_tail(&data->pages, &dreq->rewrite_list);
666 644
645 data->req = (struct nfs_page *) dreq;
667 data->inode = inode; 646 data->inode = inode;
668 data->cred = ctx->cred; 647 data->cred = ctx->cred;
669 data->args.fh = NFS_FH(inode); 648 data->args.fh = NFS_FH(inode);
670 data->args.context = ctx; 649 data->args.context = ctx;
671 data->args.offset = pos; 650 data->args.offset = pos;
672 data->args.pgbase = pgbase; 651 data->args.pgbase = pgbase;
673 data->args.pages = &pages[curpage]; 652 data->args.pages = data->pagevec;
674 data->args.count = bytes; 653 data->args.count = bytes;
675 data->res.fattr = &data->fattr; 654 data->res.fattr = &data->fattr;
676 data->res.count = bytes; 655 data->res.count = bytes;
@@ -694,19 +673,26 @@ static void nfs_direct_write_schedule(struct nfs_direct_req *dreq, int sync)
694 bytes, 673 bytes,
695 (unsigned long long)data->args.offset); 674 (unsigned long long)data->args.offset);
696 675
676 started += bytes;
677 user_addr += bytes;
697 pos += bytes; 678 pos += bytes;
698 pgbase += bytes; 679 pgbase += bytes;
699 curpage += pgbase >> PAGE_SHIFT;
700 pgbase &= ~PAGE_MASK; 680 pgbase &= ~PAGE_MASK;
701 681
702 count -= bytes; 682 count -= bytes;
703 } while (count != 0); 683 } while (count != 0);
704 BUG_ON(!list_empty(list)); 684
685 if (put_dreq(dreq))
686 nfs_direct_write_complete(dreq, inode);
687
688 if (started)
689 return 0;
690 return result < 0 ? (ssize_t) result : -EFAULT;
705} 691}
706 692
707static ssize_t nfs_direct_write(struct kiocb *iocb, unsigned long user_addr, size_t count, loff_t pos, struct page **pages, int nr_pages) 693static ssize_t nfs_direct_write(struct kiocb *iocb, unsigned long user_addr, size_t count, loff_t pos)
708{ 694{
709 ssize_t result; 695 ssize_t result = 0;
710 sigset_t oldset; 696 sigset_t oldset;
711 struct inode *inode = iocb->ki_filp->f_mapping->host; 697 struct inode *inode = iocb->ki_filp->f_mapping->host;
712 struct rpc_clnt *clnt = NFS_CLIENT(inode); 698 struct rpc_clnt *clnt = NFS_CLIENT(inode);
@@ -714,17 +700,14 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, unsigned long user_addr, siz
714 size_t wsize = NFS_SERVER(inode)->wsize; 700 size_t wsize = NFS_SERVER(inode)->wsize;
715 int sync = 0; 701 int sync = 0;
716 702
717 dreq = nfs_direct_write_alloc(count, wsize); 703 dreq = nfs_direct_req_alloc();
718 if (!dreq) 704 if (!dreq)
719 return -ENOMEM; 705 return -ENOMEM;
706 nfs_alloc_commit_data(dreq);
707
720 if (dreq->commit_data == NULL || count < wsize) 708 if (dreq->commit_data == NULL || count < wsize)
721 sync = FLUSH_STABLE; 709 sync = FLUSH_STABLE;
722 710
723 dreq->user_addr = user_addr;
724 dreq->user_count = count;
725 dreq->pos = pos;
726 dreq->pages = pages;
727 dreq->npages = nr_pages;
728 dreq->inode = inode; 711 dreq->inode = inode;
729 dreq->ctx = get_nfs_open_context((struct nfs_open_context *)iocb->ki_filp->private_data); 712 dreq->ctx = get_nfs_open_context((struct nfs_open_context *)iocb->ki_filp->private_data);
730 if (!is_sync_kiocb(iocb)) 713 if (!is_sync_kiocb(iocb))
@@ -735,8 +718,9 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, unsigned long user_addr, siz
735 nfs_begin_data_update(inode); 718 nfs_begin_data_update(inode);
736 719
737 rpc_clnt_sigmask(clnt, &oldset); 720 rpc_clnt_sigmask(clnt, &oldset);
738 nfs_direct_write_schedule(dreq, sync); 721 result = nfs_direct_write_schedule(dreq, user_addr, count, pos, sync);
739 result = nfs_direct_wait(dreq); 722 if (!result)
723 result = nfs_direct_wait(dreq);
740 rpc_clnt_sigunmask(clnt, &oldset); 724 rpc_clnt_sigunmask(clnt, &oldset);
741 725
742 return result; 726 return result;
@@ -766,8 +750,6 @@ static ssize_t nfs_direct_write(struct kiocb *iocb, unsigned long user_addr, siz
766ssize_t nfs_file_direct_read(struct kiocb *iocb, char __user *buf, size_t count, loff_t pos) 750ssize_t nfs_file_direct_read(struct kiocb *iocb, char __user *buf, size_t count, loff_t pos)
767{ 751{
768 ssize_t retval = -EINVAL; 752 ssize_t retval = -EINVAL;
769 int page_count;
770 struct page **pages;
771 struct file *file = iocb->ki_filp; 753 struct file *file = iocb->ki_filp;
772 struct address_space *mapping = file->f_mapping; 754 struct address_space *mapping = file->f_mapping;
773 755
@@ -789,14 +771,7 @@ ssize_t nfs_file_direct_read(struct kiocb *iocb, char __user *buf, size_t count,
789 if (retval) 771 if (retval)
790 goto out; 772 goto out;
791 773
792 retval = nfs_get_user_pages(READ, (unsigned long) buf, 774 retval = nfs_direct_read(iocb, (unsigned long) buf, count, pos);
793 count, &pages);
794 if (retval < 0)
795 goto out;
796 page_count = retval;
797
798 retval = nfs_direct_read(iocb, (unsigned long) buf, count, pos,
799 pages, page_count);
800 if (retval > 0) 775 if (retval > 0)
801 iocb->ki_pos = pos + retval; 776 iocb->ki_pos = pos + retval;
802 777
@@ -832,8 +807,6 @@ out:
832ssize_t nfs_file_direct_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos) 807ssize_t nfs_file_direct_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t pos)
833{ 808{
834 ssize_t retval; 809 ssize_t retval;
835 int page_count;
836 struct page **pages;
837 struct file *file = iocb->ki_filp; 810 struct file *file = iocb->ki_filp;
838 struct address_space *mapping = file->f_mapping; 811 struct address_space *mapping = file->f_mapping;
839 812
@@ -861,14 +834,7 @@ ssize_t nfs_file_direct_write(struct kiocb *iocb, const char __user *buf, size_t
861 if (retval) 834 if (retval)
862 goto out; 835 goto out;
863 836
864 retval = nfs_get_user_pages(WRITE, (unsigned long) buf, 837 retval = nfs_direct_write(iocb, (unsigned long) buf, count, pos);
865 count, &pages);
866 if (retval < 0)
867 goto out;
868 page_count = retval;
869
870 retval = nfs_direct_write(iocb, (unsigned long) buf, count,
871 pos, pages, page_count);
872 838
873 /* 839 /*
874 * XXX: nfs_end_data_update() already ensures this file's 840 * XXX: nfs_end_data_update() already ensures this file's
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index add289138836..cc2b874ad5a4 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -315,7 +315,7 @@ static int nfs_release_page(struct page *page, gfp_t gfp)
315 return !nfs_wb_page(page->mapping->host, page); 315 return !nfs_wb_page(page->mapping->host, page);
316} 316}
317 317
318struct address_space_operations nfs_file_aops = { 318const struct address_space_operations nfs_file_aops = {
319 .readpage = nfs_readpage, 319 .readpage = nfs_readpage,
320 .readpages = nfs_readpages, 320 .readpages = nfs_readpages,
321 .set_page_dirty = __set_page_dirty_nobuffers, 321 .set_page_dirty = __set_page_dirty_nobuffers,
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index c5b916605fb0..d349fb2245da 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -13,7 +13,6 @@
13 * 13 *
14 */ 14 */
15 15
16#include <linux/config.h>
17#include <linux/module.h> 16#include <linux/module.h>
18#include <linux/init.h> 17#include <linux/init.h>
19 18
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 4fe51c1292bb..e4f4e5def0fc 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -81,9 +81,9 @@ extern struct file_system_type clone_nfs_fs_type;
81#ifdef CONFIG_NFS_V4 81#ifdef CONFIG_NFS_V4
82extern struct file_system_type clone_nfs4_fs_type; 82extern struct file_system_type clone_nfs4_fs_type;
83#endif 83#endif
84#ifdef CONFIG_PROC_FS 84
85extern struct rpc_stat nfs_rpcstat; 85extern struct rpc_stat nfs_rpcstat;
86#endif 86
87extern int __init register_nfs_fs(void); 87extern int __init register_nfs_fs(void);
88extern void __exit unregister_nfs_fs(void); 88extern void __exit unregister_nfs_fs(void);
89 89
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index b4916b092194..e6ee97f19d81 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3144,9 +3144,6 @@ static int do_vfs_lock(struct file *file, struct file_lock *fl)
3144 default: 3144 default:
3145 BUG(); 3145 BUG();
3146 } 3146 }
3147 if (res < 0)
3148 printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n",
3149 __FUNCTION__);
3150 return res; 3147 return res;
3151} 3148}
3152 3149
@@ -3258,8 +3255,6 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl,
3258 return ERR_PTR(-ENOMEM); 3255 return ERR_PTR(-ENOMEM);
3259 } 3256 }
3260 3257
3261 /* Unlock _before_ we do the RPC call */
3262 do_vfs_lock(fl->fl_file, fl);
3263 return rpc_run_task(NFS_CLIENT(lsp->ls_state->inode), RPC_TASK_ASYNC, &nfs4_locku_ops, data); 3258 return rpc_run_task(NFS_CLIENT(lsp->ls_state->inode), RPC_TASK_ASYNC, &nfs4_locku_ops, data);
3264} 3259}
3265 3260
@@ -3270,30 +3265,28 @@ static int nfs4_proc_unlck(struct nfs4_state *state, int cmd, struct file_lock *
3270 struct rpc_task *task; 3265 struct rpc_task *task;
3271 int status = 0; 3266 int status = 0;
3272 3267
3273 /* Is this a delegated lock? */
3274 if (test_bit(NFS_DELEGATED_STATE, &state->flags))
3275 goto out_unlock;
3276 /* Is this open_owner holding any locks on the server? */
3277 if (test_bit(LK_STATE_IN_USE, &state->flags) == 0)
3278 goto out_unlock;
3279
3280 status = nfs4_set_lock_state(state, request); 3268 status = nfs4_set_lock_state(state, request);
3269 /* Unlock _before_ we do the RPC call */
3270 request->fl_flags |= FL_EXISTS;
3271 if (do_vfs_lock(request->fl_file, request) == -ENOENT)
3272 goto out;
3281 if (status != 0) 3273 if (status != 0)
3282 goto out_unlock; 3274 goto out;
3275 /* Is this a delegated lock? */
3276 if (test_bit(NFS_DELEGATED_STATE, &state->flags))
3277 goto out;
3283 lsp = request->fl_u.nfs4_fl.owner; 3278 lsp = request->fl_u.nfs4_fl.owner;
3284 status = -ENOMEM;
3285 seqid = nfs_alloc_seqid(&lsp->ls_seqid); 3279 seqid = nfs_alloc_seqid(&lsp->ls_seqid);
3280 status = -ENOMEM;
3286 if (seqid == NULL) 3281 if (seqid == NULL)
3287 goto out_unlock; 3282 goto out;
3288 task = nfs4_do_unlck(request, request->fl_file->private_data, lsp, seqid); 3283 task = nfs4_do_unlck(request, request->fl_file->private_data, lsp, seqid);
3289 status = PTR_ERR(task); 3284 status = PTR_ERR(task);
3290 if (IS_ERR(task)) 3285 if (IS_ERR(task))
3291 goto out_unlock; 3286 goto out;
3292 status = nfs4_wait_for_completion_rpc_task(task); 3287 status = nfs4_wait_for_completion_rpc_task(task);
3293 rpc_release_task(task); 3288 rpc_release_task(task);
3294 return status; 3289out:
3295out_unlock:
3296 do_vfs_lock(request->fl_file, request);
3297 return status; 3290 return status;
3298} 3291}
3299 3292
@@ -3461,10 +3454,10 @@ static int nfs4_lock_reclaim(struct nfs4_state *state, struct file_lock *request
3461 struct nfs4_exception exception = { }; 3454 struct nfs4_exception exception = { };
3462 int err; 3455 int err;
3463 3456
3464 /* Cache the lock if possible... */
3465 if (test_bit(NFS_DELEGATED_STATE, &state->flags))
3466 return 0;
3467 do { 3457 do {
3458 /* Cache the lock if possible... */
3459 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0)
3460 return 0;
3468 err = _nfs4_do_setlk(state, F_SETLK, request, 1); 3461 err = _nfs4_do_setlk(state, F_SETLK, request, 1);
3469 if (err != -NFS4ERR_DELAY) 3462 if (err != -NFS4ERR_DELAY)
3470 break; 3463 break;
@@ -3483,6 +3476,8 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request
3483 if (err != 0) 3476 if (err != 0)
3484 return err; 3477 return err;
3485 do { 3478 do {
3479 if (test_bit(NFS_DELEGATED_STATE, &state->flags) != 0)
3480 return 0;
3486 err = _nfs4_do_setlk(state, F_SETLK, request, 0); 3481 err = _nfs4_do_setlk(state, F_SETLK, request, 0);
3487 if (err != -NFS4ERR_DELAY) 3482 if (err != -NFS4ERR_DELAY)
3488 break; 3483 break;
@@ -3494,29 +3489,42 @@ static int nfs4_lock_expired(struct nfs4_state *state, struct file_lock *request
3494static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request) 3489static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock *request)
3495{ 3490{
3496 struct nfs4_client *clp = state->owner->so_client; 3491 struct nfs4_client *clp = state->owner->so_client;
3492 unsigned char fl_flags = request->fl_flags;
3497 int status; 3493 int status;
3498 3494
3499 /* Is this a delegated open? */ 3495 /* Is this a delegated open? */
3500 if (NFS_I(state->inode)->delegation_state != 0) {
3501 /* Yes: cache locks! */
3502 status = do_vfs_lock(request->fl_file, request);
3503 /* ...but avoid races with delegation recall... */
3504 if (status < 0 || test_bit(NFS_DELEGATED_STATE, &state->flags))
3505 return status;
3506 }
3507 down_read(&clp->cl_sem);
3508 status = nfs4_set_lock_state(state, request); 3496 status = nfs4_set_lock_state(state, request);
3509 if (status != 0) 3497 if (status != 0)
3510 goto out; 3498 goto out;
3499 request->fl_flags |= FL_ACCESS;
3500 status = do_vfs_lock(request->fl_file, request);
3501 if (status < 0)
3502 goto out;
3503 down_read(&clp->cl_sem);
3504 if (test_bit(NFS_DELEGATED_STATE, &state->flags)) {
3505 struct nfs_inode *nfsi = NFS_I(state->inode);
3506 /* Yes: cache locks! */
3507 down_read(&nfsi->rwsem);
3508 /* ...but avoid races with delegation recall... */
3509 if (test_bit(NFS_DELEGATED_STATE, &state->flags)) {
3510 request->fl_flags = fl_flags & ~FL_SLEEP;
3511 status = do_vfs_lock(request->fl_file, request);
3512 up_read(&nfsi->rwsem);
3513 goto out_unlock;
3514 }
3515 up_read(&nfsi->rwsem);
3516 }
3511 status = _nfs4_do_setlk(state, cmd, request, 0); 3517 status = _nfs4_do_setlk(state, cmd, request, 0);
3512 if (status != 0) 3518 if (status != 0)
3513 goto out; 3519 goto out_unlock;
3514 /* Note: we always want to sleep here! */ 3520 /* Note: we always want to sleep here! */
3515 request->fl_flags |= FL_SLEEP; 3521 request->fl_flags = fl_flags | FL_SLEEP;
3516 if (do_vfs_lock(request->fl_file, request) < 0) 3522 if (do_vfs_lock(request->fl_file, request) < 0)
3517 printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __FUNCTION__); 3523 printk(KERN_WARNING "%s: VFS is out of sync with lock manager!\n", __FUNCTION__);
3518out: 3524out_unlock:
3519 up_read(&clp->cl_sem); 3525 up_read(&clp->cl_sem);
3526out:
3527 request->fl_flags = fl_flags;
3520 return status; 3528 return status;
3521} 3529}
3522 3530
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 96e5b82c153b..090a36b07a22 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -38,7 +38,6 @@
38 * subsequent patch. 38 * subsequent patch.
39 */ 39 */
40 40
41#include <linux/config.h>
42#include <linux/slab.h> 41#include <linux/slab.h>
43#include <linux/smp_lock.h> 42#include <linux/smp_lock.h>
44#include <linux/nfs_fs.h> 43#include <linux/nfs_fs.h>
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index d89f6fb3b3a3..36e902a88ca1 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -9,7 +9,6 @@
9 * 9 *
10 */ 10 */
11 11
12#include <linux/config.h>
13#include <linux/slab.h> 12#include <linux/slab.h>
14#include <linux/file.h> 13#include <linux/file.h>
15#include <linux/sunrpc/clnt.h> 14#include <linux/sunrpc/clnt.h>
@@ -315,6 +314,7 @@ nfs_scan_lock_dirty(struct nfs_inode *nfsi, struct list_head *dst,
315 req->wb_index, NFS_PAGE_TAG_DIRTY); 314 req->wb_index, NFS_PAGE_TAG_DIRTY);
316 nfs_list_remove_request(req); 315 nfs_list_remove_request(req);
317 nfs_list_add_request(req, dst); 316 nfs_list_add_request(req, dst);
317 dec_zone_page_state(req->wb_page, NR_FILE_DIRTY);
318 res++; 318 res++;
319 } 319 }
320 } 320 }
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 32cf3773af0c..52bf634260a1 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -15,7 +15,6 @@
15 * within the RPC code when root squashing is suspected. 15 * within the RPC code when root squashing is suspected.
16 */ 16 */
17 17
18#include <linux/config.h>
19#include <linux/time.h> 18#include <linux/time.h>
20#include <linux/kernel.h> 19#include <linux/kernel.h>
21#include <linux/errno.h> 20#include <linux/errno.h>
diff --git a/fs/nfs/sysctl.c b/fs/nfs/sysctl.c
index db61e51bb154..2fe3403c2409 100644
--- a/fs/nfs/sysctl.c
+++ b/fs/nfs/sysctl.c
@@ -3,7 +3,6 @@
3 * 3 *
4 * Sysctl interface to NFS parameters 4 * Sysctl interface to NFS parameters
5 */ 5 */
6#include <linux/config.h>
7#include <linux/types.h> 6#include <linux/types.h>
8#include <linux/linkage.h> 7#include <linux/linkage.h>
9#include <linux/ctype.h> 8#include <linux/ctype.h>
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 8fccb9cb173b..86bac6a5008e 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -46,7 +46,6 @@
46 * Copyright (C) 1996, 1997, Olaf Kirch <okir@monad.swb.de> 46 * Copyright (C) 1996, 1997, Olaf Kirch <okir@monad.swb.de>
47 */ 47 */
48 48
49#include <linux/config.h>
50#include <linux/types.h> 49#include <linux/types.h>
51#include <linux/slab.h> 50#include <linux/slab.h>
52#include <linux/mm.h> 51#include <linux/mm.h>
@@ -497,7 +496,7 @@ nfs_mark_request_dirty(struct nfs_page *req)
497 nfs_list_add_request(req, &nfsi->dirty); 496 nfs_list_add_request(req, &nfsi->dirty);
498 nfsi->ndirty++; 497 nfsi->ndirty++;
499 spin_unlock(&nfsi->req_lock); 498 spin_unlock(&nfsi->req_lock);
500 inc_page_state(nr_dirty); 499 inc_zone_page_state(req->wb_page, NR_FILE_DIRTY);
501 mark_inode_dirty(inode); 500 mark_inode_dirty(inode);
502} 501}
503 502
@@ -525,7 +524,7 @@ nfs_mark_request_commit(struct nfs_page *req)
525 nfs_list_add_request(req, &nfsi->commit); 524 nfs_list_add_request(req, &nfsi->commit);
526 nfsi->ncommit++; 525 nfsi->ncommit++;
527 spin_unlock(&nfsi->req_lock); 526 spin_unlock(&nfsi->req_lock);
528 inc_page_state(nr_unstable); 527 inc_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
529 mark_inode_dirty(inode); 528 mark_inode_dirty(inode);
530} 529}
531#endif 530#endif
@@ -579,7 +578,7 @@ static int nfs_wait_on_requests(struct inode *inode, unsigned long idx_start, un
579 return ret; 578 return ret;
580} 579}
581 580
582static void nfs_cancel_requests(struct list_head *head) 581static void nfs_cancel_dirty_list(struct list_head *head)
583{ 582{
584 struct nfs_page *req; 583 struct nfs_page *req;
585 while(!list_empty(head)) { 584 while(!list_empty(head)) {
@@ -590,6 +589,19 @@ static void nfs_cancel_requests(struct list_head *head)
590 } 589 }
591} 590}
592 591
592static void nfs_cancel_commit_list(struct list_head *head)
593{
594 struct nfs_page *req;
595
596 while(!list_empty(head)) {
597 req = nfs_list_entry(head->next);
598 nfs_list_remove_request(req);
599 nfs_inode_remove_request(req);
600 nfs_clear_page_writeback(req);
601 dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
602 }
603}
604
593/* 605/*
594 * nfs_scan_dirty - Scan an inode for dirty requests 606 * nfs_scan_dirty - Scan an inode for dirty requests
595 * @inode: NFS inode to scan 607 * @inode: NFS inode to scan
@@ -609,7 +621,6 @@ nfs_scan_dirty(struct inode *inode, struct list_head *dst, unsigned long idx_sta
609 if (nfsi->ndirty != 0) { 621 if (nfsi->ndirty != 0) {
610 res = nfs_scan_lock_dirty(nfsi, dst, idx_start, npages); 622 res = nfs_scan_lock_dirty(nfsi, dst, idx_start, npages);
611 nfsi->ndirty -= res; 623 nfsi->ndirty -= res;
612 sub_page_state(nr_dirty,res);
613 if ((nfsi->ndirty == 0) != list_empty(&nfsi->dirty)) 624 if ((nfsi->ndirty == 0) != list_empty(&nfsi->dirty))
614 printk(KERN_ERR "NFS: desynchronized value of nfs_i.ndirty.\n"); 625 printk(KERN_ERR "NFS: desynchronized value of nfs_i.ndirty.\n");
615 } 626 }
@@ -1383,6 +1394,7 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how)
1383 nfs_list_remove_request(req); 1394 nfs_list_remove_request(req);
1384 nfs_mark_request_commit(req); 1395 nfs_mark_request_commit(req);
1385 nfs_clear_page_writeback(req); 1396 nfs_clear_page_writeback(req);
1397 dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
1386 } 1398 }
1387 return -ENOMEM; 1399 return -ENOMEM;
1388} 1400}
@@ -1394,7 +1406,6 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata)
1394{ 1406{
1395 struct nfs_write_data *data = calldata; 1407 struct nfs_write_data *data = calldata;
1396 struct nfs_page *req; 1408 struct nfs_page *req;
1397 int res = 0;
1398 1409
1399 dprintk("NFS: %4d nfs_commit_done (status %d)\n", 1410 dprintk("NFS: %4d nfs_commit_done (status %d)\n",
1400 task->tk_pid, task->tk_status); 1411 task->tk_pid, task->tk_status);
@@ -1406,6 +1417,7 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata)
1406 while (!list_empty(&data->pages)) { 1417 while (!list_empty(&data->pages)) {
1407 req = nfs_list_entry(data->pages.next); 1418 req = nfs_list_entry(data->pages.next);
1408 nfs_list_remove_request(req); 1419 nfs_list_remove_request(req);
1420 dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
1409 1421
1410 dprintk("NFS: commit (%s/%Ld %d@%Ld)", 1422 dprintk("NFS: commit (%s/%Ld %d@%Ld)",
1411 req->wb_context->dentry->d_inode->i_sb->s_id, 1423 req->wb_context->dentry->d_inode->i_sb->s_id,
@@ -1432,9 +1444,7 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata)
1432 nfs_mark_request_dirty(req); 1444 nfs_mark_request_dirty(req);
1433 next: 1445 next:
1434 nfs_clear_page_writeback(req); 1446 nfs_clear_page_writeback(req);
1435 res++;
1436 } 1447 }
1437 sub_page_state(nr_unstable,res);
1438} 1448}
1439 1449
1440static const struct rpc_call_ops nfs_commit_ops = { 1450static const struct rpc_call_ops nfs_commit_ops = {
@@ -1503,7 +1513,7 @@ int nfs_sync_inode_wait(struct inode *inode, unsigned long idx_start,
1503 if (pages != 0) { 1513 if (pages != 0) {
1504 spin_unlock(&nfsi->req_lock); 1514 spin_unlock(&nfsi->req_lock);
1505 if (how & FLUSH_INVALIDATE) 1515 if (how & FLUSH_INVALIDATE)
1506 nfs_cancel_requests(&head); 1516 nfs_cancel_dirty_list(&head);
1507 else 1517 else
1508 ret = nfs_flush_list(inode, &head, pages, how); 1518 ret = nfs_flush_list(inode, &head, pages, how);
1509 spin_lock(&nfsi->req_lock); 1519 spin_lock(&nfsi->req_lock);
@@ -1516,7 +1526,7 @@ int nfs_sync_inode_wait(struct inode *inode, unsigned long idx_start,
1516 break; 1526 break;
1517 if (how & FLUSH_INVALIDATE) { 1527 if (how & FLUSH_INVALIDATE) {
1518 spin_unlock(&nfsi->req_lock); 1528 spin_unlock(&nfsi->req_lock);
1519 nfs_cancel_requests(&head); 1529 nfs_cancel_commit_list(&head);
1520 spin_lock(&nfsi->req_lock); 1530 spin_lock(&nfsi->req_lock);
1521 continue; 1531 continue;
1522 } 1532 }
diff --git a/fs/nfsctl.c b/fs/nfsctl.c
index a5a18d4aca40..c043136a82ca 100644
--- a/fs/nfsctl.c
+++ b/fs/nfsctl.c
@@ -4,7 +4,6 @@
4 * This should eventually move to userland. 4 * This should eventually move to userland.
5 * 5 *
6 */ 6 */
7#include <linux/config.h>
8#include <linux/types.h> 7#include <linux/types.h>
9#include <linux/file.h> 8#include <linux/file.h>
10#include <linux/fs.h> 9#include <linux/fs.h>
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index 3eec30000f3f..01bc68c628ad 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -126,7 +126,7 @@ static int expkey_parse(struct cache_detail *cd, char *mesg, int mlen)
126 if (*ep) 126 if (*ep)
127 goto out; 127 goto out;
128 dprintk("found fsidtype %d\n", fsidtype); 128 dprintk("found fsidtype %d\n", fsidtype);
129 if (fsidtype > 2) 129 if (key_len(fsidtype)==0) /* invalid type */
130 goto out; 130 goto out;
131 if ((len=qword_get(&mesg, buf, PAGE_SIZE)) <= 0) 131 if ((len=qword_get(&mesg, buf, PAGE_SIZE)) <= 0)
132 goto out; 132 goto out;
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c
index dbaf3f93f328..54b37b1d2e3a 100644
--- a/fs/nfsd/nfs4callback.c
+++ b/fs/nfsd/nfs4callback.c
@@ -33,7 +33,6 @@
33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */ 34 */
35 35
36#include <linux/config.h>
37#include <linux/module.h> 36#include <linux/module.h>
38#include <linux/list.h> 37#include <linux/list.h>
39#include <linux/inet.h> 38#include <linux/inet.h>
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c
index 4b6aa60dfceb..bea6b9478114 100644
--- a/fs/nfsd/nfs4idmap.c
+++ b/fs/nfsd/nfs4idmap.c
@@ -34,7 +34,6 @@
34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */ 35 */
36 36
37#include <linux/config.h>
38#include <linux/module.h> 37#include <linux/module.h>
39#include <linux/init.h> 38#include <linux/init.h>
40 39
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index b0e095ea0c03..ee4eff27aedc 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -721,6 +721,12 @@ nfsd4_proc_null(struct svc_rqst *rqstp, void *argp, void *resp)
721 return nfs_ok; 721 return nfs_ok;
722} 722}
723 723
724static inline void nfsd4_increment_op_stats(u32 opnum)
725{
726 if (opnum >= FIRST_NFS4_OP && opnum <= LAST_NFS4_OP)
727 nfsdstats.nfs4_opcount[opnum]++;
728}
729
724 730
725/* 731/*
726 * COMPOUND call. 732 * COMPOUND call.
@@ -930,6 +936,8 @@ encode_op:
930 /* XXX Ugh, we need to get rid of this kind of special case: */ 936 /* XXX Ugh, we need to get rid of this kind of special case: */
931 if (op->opnum == OP_READ && op->u.read.rd_filp) 937 if (op->opnum == OP_READ && op->u.read.rd_filp)
932 fput(op->u.read.rd_filp); 938 fput(op->u.read.rd_filp);
939
940 nfsd4_increment_op_stats(op->opnum);
933 } 941 }
934 942
935out: 943out:
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 7c7d01672d35..9daa0b9feb8d 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1237,8 +1237,15 @@ find_file(struct inode *ino)
1237 return NULL; 1237 return NULL;
1238} 1238}
1239 1239
1240#define TEST_ACCESS(x) ((x > 0 || x < 4)?1:0) 1240static int access_valid(u32 x)
1241#define TEST_DENY(x) ((x >= 0 || x < 5)?1:0) 1241{
1242 return (x > 0 && x < 4);
1243}
1244
1245static int deny_valid(u32 x)
1246{
1247 return (x >= 0 && x < 5);
1248}
1242 1249
1243static void 1250static void
1244set_access(unsigned int *access, unsigned long bmap) { 1251set_access(unsigned int *access, unsigned long bmap) {
@@ -1745,7 +1752,8 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
1745 int status; 1752 int status;
1746 1753
1747 status = nfserr_inval; 1754 status = nfserr_inval;
1748 if (!TEST_ACCESS(open->op_share_access) || !TEST_DENY(open->op_share_deny)) 1755 if (!access_valid(open->op_share_access)
1756 || !deny_valid(open->op_share_deny))
1749 goto out; 1757 goto out;
1750 /* 1758 /*
1751 * Lookup file; if found, lookup stateid and check open request, 1759 * Lookup file; if found, lookup stateid and check open request,
@@ -1782,10 +1790,10 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf
1782 } else { 1790 } else {
1783 /* Stateid was not found, this is a new OPEN */ 1791 /* Stateid was not found, this is a new OPEN */
1784 int flags = 0; 1792 int flags = 0;
1793 if (open->op_share_access & NFS4_SHARE_ACCESS_READ)
1794 flags |= MAY_READ;
1785 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) 1795 if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE)
1786 flags = MAY_WRITE; 1796 flags |= MAY_WRITE;
1787 else
1788 flags = MAY_READ;
1789 status = nfs4_new_open(rqstp, &stp, dp, current_fh, flags); 1797 status = nfs4_new_open(rqstp, &stp, dp, current_fh, flags);
1790 if (status) 1798 if (status)
1791 goto out; 1799 goto out;
@@ -2070,16 +2078,12 @@ nfs4_preprocess_stateid_op(struct svc_fh *current_fh, stateid_t *stateid, int fl
2070 if (!stateid->si_fileid) { /* delegation stateid */ 2078 if (!stateid->si_fileid) { /* delegation stateid */
2071 if(!(dp = find_delegation_stateid(ino, stateid))) { 2079 if(!(dp = find_delegation_stateid(ino, stateid))) {
2072 dprintk("NFSD: delegation stateid not found\n"); 2080 dprintk("NFSD: delegation stateid not found\n");
2073 if (nfs4_in_grace())
2074 status = nfserr_grace;
2075 goto out; 2081 goto out;
2076 } 2082 }
2077 stidp = &dp->dl_stateid; 2083 stidp = &dp->dl_stateid;
2078 } else { /* open or lock stateid */ 2084 } else { /* open or lock stateid */
2079 if (!(stp = find_stateid(stateid, flags))) { 2085 if (!(stp = find_stateid(stateid, flags))) {
2080 dprintk("NFSD: open or lock stateid not found\n"); 2086 dprintk("NFSD: open or lock stateid not found\n");
2081 if (nfs4_in_grace())
2082 status = nfserr_grace;
2083 goto out; 2087 goto out;
2084 } 2088 }
2085 if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp)) 2089 if ((flags & CHECK_FH) && nfs4_check_fh(current_fh, stp))
@@ -2252,8 +2256,9 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfs
2252 (int)current_fh->fh_dentry->d_name.len, 2256 (int)current_fh->fh_dentry->d_name.len,
2253 current_fh->fh_dentry->d_name.name); 2257 current_fh->fh_dentry->d_name.name);
2254 2258
2255 if ((status = fh_verify(rqstp, current_fh, S_IFREG, 0))) 2259 status = fh_verify(rqstp, current_fh, S_IFREG, 0);
2256 goto out; 2260 if (status)
2261 return status;
2257 2262
2258 nfs4_lock_state(); 2263 nfs4_lock_state();
2259 2264
@@ -2320,7 +2325,8 @@ nfsd4_open_downgrade(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct n
2320 (int)current_fh->fh_dentry->d_name.len, 2325 (int)current_fh->fh_dentry->d_name.len,
2321 current_fh->fh_dentry->d_name.name); 2326 current_fh->fh_dentry->d_name.name);
2322 2327
2323 if (!TEST_ACCESS(od->od_share_access) || !TEST_DENY(od->od_share_deny)) 2328 if (!access_valid(od->od_share_access)
2329 || !deny_valid(od->od_share_deny))
2324 return nfserr_inval; 2330 return nfserr_inval;
2325 2331
2326 nfs4_lock_state(); 2332 nfs4_lock_state();
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index a1810e6a93e5..7046ac9cf97f 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -6,7 +6,6 @@
6 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> 6 * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de>
7 */ 7 */
8 8
9#include <linux/config.h>
10#include <linux/module.h> 9#include <linux/module.h>
11 10
12#include <linux/linkage.h> 11#include <linux/linkage.h>
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
index 3f2ec2e6d06c..ecc439d2565f 100644
--- a/fs/nfsd/nfsfh.c
+++ b/fs/nfsd/nfsfh.c
@@ -187,13 +187,6 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
187 goto out; 187 goto out;
188 } 188 }
189 189
190 /* Set user creds for this exportpoint */
191 error = nfsd_setuser(rqstp, exp);
192 if (error) {
193 error = nfserrno(error);
194 goto out;
195 }
196
197 /* 190 /*
198 * Look up the dentry using the NFS file handle. 191 * Look up the dentry using the NFS file handle.
199 */ 192 */
@@ -251,6 +244,14 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access)
251 } 244 }
252 cache_get(&exp->h); 245 cache_get(&exp->h);
253 246
247 /* Set user creds for this exportpoint; necessary even in the "just
248 * checking" case because this may be a filehandle that was created by
249 * fh_compose, and that is about to be used in another nfsv4 compound
250 * operation */
251 error = nfserrno(nfsd_setuser(rqstp, exp));
252 if (error)
253 goto out;
254
254 error = nfsd_mode_check(rqstp, dentry->d_inode->i_mode, type); 255 error = nfsd_mode_check(rqstp, dentry->d_inode->i_mode, type);
255 if (error) 256 if (error)
256 goto out; 257 goto out;
@@ -312,8 +313,8 @@ int
312fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, struct svc_fh *ref_fh) 313fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, struct svc_fh *ref_fh)
313{ 314{
314 /* ref_fh is a reference file handle. 315 /* ref_fh is a reference file handle.
315 * if it is non-null, then we should compose a filehandle which is 316 * if it is non-null and for the same filesystem, then we should compose
316 * of the same version, where possible. 317 * a filehandle which is of the same version, where possible.
317 * Currently, that means that if ref_fh->fh_handle.fh_version == 0xca 318 * Currently, that means that if ref_fh->fh_handle.fh_version == 0xca
318 * Then create a 32byte filehandle using nfs_fhbase_old 319 * Then create a 32byte filehandle using nfs_fhbase_old
319 * 320 *
@@ -332,7 +333,7 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, st
332 parent->d_name.name, dentry->d_name.name, 333 parent->d_name.name, dentry->d_name.name,
333 (inode ? inode->i_ino : 0)); 334 (inode ? inode->i_ino : 0));
334 335
335 if (ref_fh) { 336 if (ref_fh && ref_fh->fh_export == exp) {
336 ref_fh_version = ref_fh->fh_handle.fh_version; 337 ref_fh_version = ref_fh->fh_handle.fh_version;
337 if (ref_fh_version == 0xca) 338 if (ref_fh_version == 0xca)
338 ref_fh_fsid_type = 0; 339 ref_fh_fsid_type = 0;
@@ -461,7 +462,7 @@ fh_update(struct svc_fh *fhp)
461 } else { 462 } else {
462 int size; 463 int size;
463 if (fhp->fh_handle.fh_fileid_type != 0) 464 if (fhp->fh_handle.fh_fileid_type != 0)
464 goto out_uptodate; 465 goto out;
465 datap = fhp->fh_handle.fh_auth+ 466 datap = fhp->fh_handle.fh_auth+
466 fhp->fh_handle.fh_size/4 -1; 467 fhp->fh_handle.fh_size/4 -1;
467 size = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4; 468 size = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4;
@@ -481,10 +482,6 @@ out_negative:
481 printk(KERN_ERR "fh_update: %s/%s still negative!\n", 482 printk(KERN_ERR "fh_update: %s/%s still negative!\n",
482 dentry->d_parent->d_name.name, dentry->d_name.name); 483 dentry->d_parent->d_name.name, dentry->d_name.name);
483 goto out; 484 goto out;
484out_uptodate:
485 printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n",
486 dentry->d_parent->d_name.name, dentry->d_name.name);
487 goto out;
488} 485}
489 486
490/* 487/*
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
index 3790727e5dfd..ec1decf29bab 100644
--- a/fs/nfsd/nfssvc.c
+++ b/fs/nfsd/nfssvc.c
@@ -8,7 +8,6 @@
8 * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de> 8 * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
9 */ 9 */
10 10
11#include <linux/config.h>
12#include <linux/module.h> 11#include <linux/module.h>
13 12
14#include <linux/time.h> 13#include <linux/time.h>
diff --git a/fs/nfsd/stats.c b/fs/nfsd/stats.c
index 57265d563804..71944cddf680 100644
--- a/fs/nfsd/stats.c
+++ b/fs/nfsd/stats.c
@@ -72,6 +72,16 @@ static int nfsd_proc_show(struct seq_file *seq, void *v)
72 /* show my rpc info */ 72 /* show my rpc info */
73 svc_seq_show(seq, &nfsd_svcstats); 73 svc_seq_show(seq, &nfsd_svcstats);
74 74
75#ifdef CONFIG_NFSD_V4
76 /* Show count for individual nfsv4 operations */
77 /* Writing operation numbers 0 1 2 also for maintaining uniformity */
78 seq_printf(seq,"proc4ops %u", LAST_NFS4_OP + 1);
79 for (i = 0; i <= LAST_NFS4_OP; i++)
80 seq_printf(seq, " %u", nfsdstats.nfs4_opcount[i]);
81
82 seq_putc(seq, '\n');
83#endif
84
75 return 0; 85 return 0;
76} 86}
77 87
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 245eaa1fb59b..c9e3b5a8fe07 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -16,7 +16,6 @@
16 * Zerocpy NFS support (C) 2002 Hirokazu Takahashi <taka@valinux.co.jp> 16 * Zerocpy NFS support (C) 2002 Hirokazu Takahashi <taka@valinux.co.jp>
17 */ 17 */
18 18
19#include <linux/config.h>
20#include <linux/string.h> 19#include <linux/string.h>
21#include <linux/time.h> 20#include <linux/time.h>
22#include <linux/errno.h> 21#include <linux/errno.h>
@@ -673,7 +672,10 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type,
673 goto out_nfserr; 672 goto out_nfserr;
674 673
675 if (access & MAY_WRITE) { 674 if (access & MAY_WRITE) {
676 flags = O_WRONLY|O_LARGEFILE; 675 if (access & MAY_READ)
676 flags = O_RDWR|O_LARGEFILE;
677 else
678 flags = O_WRONLY|O_LARGEFILE;
677 679
678 DQUOT_INIT(inode); 680 DQUOT_INIT(inode);
679 } 681 }
@@ -834,7 +836,7 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
834 if (ra && ra->p_set) 836 if (ra && ra->p_set)
835 file->f_ra = ra->p_ra; 837 file->f_ra = ra->p_ra;
836 838
837 if (file->f_op->sendfile) { 839 if (file->f_op->sendfile && rqstp->rq_sendfile_ok) {
838 svc_pushback_unused_pages(rqstp); 840 svc_pushback_unused_pages(rqstp);
839 err = file->f_op->sendfile(file, &offset, *count, 841 err = file->f_op->sendfile(file, &offset, *count,
840 nfsd_read_actor, rqstp); 842 nfsd_read_actor, rqstp);
@@ -1517,14 +1519,15 @@ nfsd_link(struct svc_rqst *rqstp, struct svc_fh *ffhp,
1517 err = nfserrno(err); 1519 err = nfserrno(err);
1518 } 1520 }
1519 1521
1520 fh_unlock(ffhp);
1521 dput(dnew); 1522 dput(dnew);
1523out_unlock:
1524 fh_unlock(ffhp);
1522out: 1525out:
1523 return err; 1526 return err;
1524 1527
1525out_nfserr: 1528out_nfserr:
1526 err = nfserrno(err); 1529 err = nfserrno(err);
1527 goto out; 1530 goto out_unlock;
1528} 1531}
1529 1532
1530/* 1533/*
@@ -1553,7 +1556,7 @@ nfsd_rename(struct svc_rqst *rqstp, struct svc_fh *ffhp, char *fname, int flen,
1553 tdir = tdentry->d_inode; 1556 tdir = tdentry->d_inode;
1554 1557
1555 err = (rqstp->rq_vers == 2) ? nfserr_acces : nfserr_xdev; 1558 err = (rqstp->rq_vers == 2) ? nfserr_acces : nfserr_xdev;
1556 if (fdir->i_sb != tdir->i_sb) 1559 if (ffhp->fh_export != tfhp->fh_export)
1557 goto out; 1560 goto out;
1558 1561
1559 err = nfserr_perm; 1562 err = nfserr_perm;
diff --git a/fs/nls/nls_base.c b/fs/nls/nls_base.c
index a912debcd20b..9de6b495f112 100644
--- a/fs/nls/nls_base.c
+++ b/fs/nls/nls_base.c
@@ -10,7 +10,6 @@
10 10
11#include <linux/module.h> 11#include <linux/module.h>
12#include <linux/string.h> 12#include <linux/string.h>
13#include <linux/config.h>
14#include <linux/nls.h> 13#include <linux/nls.h>
15#include <linux/kernel.h> 14#include <linux/kernel.h>
16#include <linux/errno.h> 15#include <linux/errno.h>
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c
index 580412d330cb..bc579bfdfbd8 100644
--- a/fs/ntfs/aops.c
+++ b/fs/ntfs/aops.c
@@ -1544,7 +1544,7 @@ err_out:
1544/** 1544/**
1545 * ntfs_aops - general address space operations for inodes and attributes 1545 * ntfs_aops - general address space operations for inodes and attributes
1546 */ 1546 */
1547struct address_space_operations ntfs_aops = { 1547const struct address_space_operations ntfs_aops = {
1548 .readpage = ntfs_readpage, /* Fill page with data. */ 1548 .readpage = ntfs_readpage, /* Fill page with data. */
1549 .sync_page = block_sync_page, /* Currently, just unplugs the 1549 .sync_page = block_sync_page, /* Currently, just unplugs the
1550 disk request queue. */ 1550 disk request queue. */
@@ -1560,7 +1560,7 @@ struct address_space_operations ntfs_aops = {
1560 * ntfs_mst_aops - general address space operations for mst protecteed inodes 1560 * ntfs_mst_aops - general address space operations for mst protecteed inodes
1561 * and attributes 1561 * and attributes
1562 */ 1562 */
1563struct address_space_operations ntfs_mst_aops = { 1563const struct address_space_operations ntfs_mst_aops = {
1564 .readpage = ntfs_readpage, /* Fill page with data. */ 1564 .readpage = ntfs_readpage, /* Fill page with data. */
1565 .sync_page = block_sync_page, /* Currently, just unplugs the 1565 .sync_page = block_sync_page, /* Currently, just unplugs the
1566 disk request queue. */ 1566 disk request queue. */
diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c
index 4c86b7e1d1eb..d313f356e66a 100644
--- a/fs/ntfs/inode.c
+++ b/fs/ntfs/inode.c
@@ -367,6 +367,12 @@ static void ntfs_destroy_extent_inode(ntfs_inode *ni)
367 kmem_cache_free(ntfs_inode_cache, ni); 367 kmem_cache_free(ntfs_inode_cache, ni);
368} 368}
369 369
370/*
371 * The attribute runlist lock has separate locking rules from the
372 * normal runlist lock, so split the two lock-classes:
373 */
374static struct lock_class_key attr_list_rl_lock_class;
375
370/** 376/**
371 * __ntfs_init_inode - initialize ntfs specific part of an inode 377 * __ntfs_init_inode - initialize ntfs specific part of an inode
372 * @sb: super block of mounted volume 378 * @sb: super block of mounted volume
@@ -394,6 +400,8 @@ void __ntfs_init_inode(struct super_block *sb, ntfs_inode *ni)
394 ni->attr_list_size = 0; 400 ni->attr_list_size = 0;
395 ni->attr_list = NULL; 401 ni->attr_list = NULL;
396 ntfs_init_runlist(&ni->attr_list_rl); 402 ntfs_init_runlist(&ni->attr_list_rl);
403 lockdep_set_class(&ni->attr_list_rl.lock,
404 &attr_list_rl_lock_class);
397 ni->itype.index.bmp_ino = NULL; 405 ni->itype.index.bmp_ino = NULL;
398 ni->itype.index.block_size = 0; 406 ni->itype.index.block_size = 0;
399 ni->itype.index.vcn_size = 0; 407 ni->itype.index.vcn_size = 0;
@@ -405,6 +413,13 @@ void __ntfs_init_inode(struct super_block *sb, ntfs_inode *ni)
405 ni->ext.base_ntfs_ino = NULL; 413 ni->ext.base_ntfs_ino = NULL;
406} 414}
407 415
416/*
417 * Extent inodes get MFT-mapped in a nested way, while the base inode
418 * is still mapped. Teach this nesting to the lock validator by creating
419 * a separate class for nested inode's mrec_lock's:
420 */
421static struct lock_class_key extent_inode_mrec_lock_key;
422
408inline ntfs_inode *ntfs_new_extent_inode(struct super_block *sb, 423inline ntfs_inode *ntfs_new_extent_inode(struct super_block *sb,
409 unsigned long mft_no) 424 unsigned long mft_no)
410{ 425{
@@ -413,6 +428,7 @@ inline ntfs_inode *ntfs_new_extent_inode(struct super_block *sb,
413 ntfs_debug("Entering."); 428 ntfs_debug("Entering.");
414 if (likely(ni != NULL)) { 429 if (likely(ni != NULL)) {
415 __ntfs_init_inode(sb, ni); 430 __ntfs_init_inode(sb, ni);
431 lockdep_set_class(&ni->mrec_lock, &extent_inode_mrec_lock_key);
416 ni->mft_no = mft_no; 432 ni->mft_no = mft_no;
417 ni->type = AT_UNUSED; 433 ni->type = AT_UNUSED;
418 ni->name = NULL; 434 ni->name = NULL;
@@ -1722,6 +1738,15 @@ err_out:
1722 return err; 1738 return err;
1723} 1739}
1724 1740
1741/*
1742 * The MFT inode has special locking, so teach the lock validator
1743 * about this by splitting off the locking rules of the MFT from
1744 * the locking rules of other inodes. The MFT inode can never be
1745 * accessed from the VFS side (or even internally), only by the
1746 * map_mft functions.
1747 */
1748static struct lock_class_key mft_ni_runlist_lock_key, mft_ni_mrec_lock_key;
1749
1725/** 1750/**
1726 * ntfs_read_inode_mount - special read_inode for mount time use only 1751 * ntfs_read_inode_mount - special read_inode for mount time use only
1727 * @vi: inode to read 1752 * @vi: inode to read
@@ -2148,6 +2173,14 @@ int ntfs_read_inode_mount(struct inode *vi)
2148 ntfs_attr_put_search_ctx(ctx); 2173 ntfs_attr_put_search_ctx(ctx);
2149 ntfs_debug("Done."); 2174 ntfs_debug("Done.");
2150 ntfs_free(m); 2175 ntfs_free(m);
2176
2177 /*
2178 * Split the locking rules of the MFT inode from the
2179 * locking rules of other inodes:
2180 */
2181 lockdep_set_class(&ni->runlist.lock, &mft_ni_runlist_lock_key);
2182 lockdep_set_class(&ni->mrec_lock, &mft_ni_mrec_lock_key);
2183
2151 return 0; 2184 return 0;
2152 2185
2153em_put_err_out: 2186em_put_err_out:
diff --git a/fs/ntfs/ntfs.h b/fs/ntfs/ntfs.h
index bf7b3d7c0930..ddd3d503097c 100644
--- a/fs/ntfs/ntfs.h
+++ b/fs/ntfs/ntfs.h
@@ -57,8 +57,8 @@ extern struct kmem_cache *ntfs_attr_ctx_cache;
57extern struct kmem_cache *ntfs_index_ctx_cache; 57extern struct kmem_cache *ntfs_index_ctx_cache;
58 58
59/* The various operations structs defined throughout the driver files. */ 59/* The various operations structs defined throughout the driver files. */
60extern struct address_space_operations ntfs_aops; 60extern const struct address_space_operations ntfs_aops;
61extern struct address_space_operations ntfs_mst_aops; 61extern const struct address_space_operations ntfs_mst_aops;
62 62
63extern const struct file_operations ntfs_file_ops; 63extern const struct file_operations ntfs_file_ops;
64extern struct inode_operations ntfs_file_inode_ops; 64extern struct inode_operations ntfs_file_inode_ops;
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 0e14acea3f8b..74e0ee8fce72 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -1724,6 +1724,14 @@ upcase_failed:
1724 return FALSE; 1724 return FALSE;
1725} 1725}
1726 1726
1727/*
1728 * The lcn and mft bitmap inodes are NTFS-internal inodes with
1729 * their own special locking rules:
1730 */
1731static struct lock_class_key
1732 lcnbmp_runlist_lock_key, lcnbmp_mrec_lock_key,
1733 mftbmp_runlist_lock_key, mftbmp_mrec_lock_key;
1734
1727/** 1735/**
1728 * load_system_files - open the system files using normal functions 1736 * load_system_files - open the system files using normal functions
1729 * @vol: ntfs super block describing device whose system files to load 1737 * @vol: ntfs super block describing device whose system files to load
@@ -1780,6 +1788,10 @@ static BOOL load_system_files(ntfs_volume *vol)
1780 ntfs_error(sb, "Failed to load $MFT/$BITMAP attribute."); 1788 ntfs_error(sb, "Failed to load $MFT/$BITMAP attribute.");
1781 goto iput_mirr_err_out; 1789 goto iput_mirr_err_out;
1782 } 1790 }
1791 lockdep_set_class(&NTFS_I(vol->mftbmp_ino)->runlist.lock,
1792 &mftbmp_runlist_lock_key);
1793 lockdep_set_class(&NTFS_I(vol->mftbmp_ino)->mrec_lock,
1794 &mftbmp_mrec_lock_key);
1783 /* Read upcase table and setup @vol->upcase and @vol->upcase_len. */ 1795 /* Read upcase table and setup @vol->upcase and @vol->upcase_len. */
1784 if (!load_and_init_upcase(vol)) 1796 if (!load_and_init_upcase(vol))
1785 goto iput_mftbmp_err_out; 1797 goto iput_mftbmp_err_out;
@@ -1802,6 +1814,11 @@ static BOOL load_system_files(ntfs_volume *vol)
1802 iput(vol->lcnbmp_ino); 1814 iput(vol->lcnbmp_ino);
1803 goto bitmap_failed; 1815 goto bitmap_failed;
1804 } 1816 }
1817 lockdep_set_class(&NTFS_I(vol->lcnbmp_ino)->runlist.lock,
1818 &lcnbmp_runlist_lock_key);
1819 lockdep_set_class(&NTFS_I(vol->lcnbmp_ino)->mrec_lock,
1820 &lcnbmp_mrec_lock_key);
1821
1805 NInoSetSparseDisabled(NTFS_I(vol->lcnbmp_ino)); 1822 NInoSetSparseDisabled(NTFS_I(vol->lcnbmp_ino));
1806 if ((vol->nr_clusters + 7) >> 3 > i_size_read(vol->lcnbmp_ino)) { 1823 if ((vol->nr_clusters + 7) >> 3 > i_size_read(vol->lcnbmp_ino)) {
1807 iput(vol->lcnbmp_ino); 1824 iput(vol->lcnbmp_ino);
@@ -2743,6 +2760,17 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
2743 struct inode *tmp_ino; 2760 struct inode *tmp_ino;
2744 int blocksize, result; 2761 int blocksize, result;
2745 2762
2763 /*
2764 * We do a pretty difficult piece of bootstrap by reading the
2765 * MFT (and other metadata) from disk into memory. We'll only
2766 * release this metadata during umount, so the locking patterns
2767 * observed during bootstrap do not count. So turn off the
2768 * observation of locking patterns (strictly for this context
2769 * only) while mounting NTFS. [The validator is still active
2770 * otherwise, even for this context: it will for example record
2771 * lock class registrations.]
2772 */
2773 lockdep_off();
2746 ntfs_debug("Entering."); 2774 ntfs_debug("Entering.");
2747#ifndef NTFS_RW 2775#ifndef NTFS_RW
2748 sb->s_flags |= MS_RDONLY; 2776 sb->s_flags |= MS_RDONLY;
@@ -2754,6 +2782,7 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
2754 if (!silent) 2782 if (!silent)
2755 ntfs_error(sb, "Allocation of NTFS volume structure " 2783 ntfs_error(sb, "Allocation of NTFS volume structure "
2756 "failed. Aborting mount..."); 2784 "failed. Aborting mount...");
2785 lockdep_on();
2757 return -ENOMEM; 2786 return -ENOMEM;
2758 } 2787 }
2759 /* Initialize ntfs_volume structure. */ 2788 /* Initialize ntfs_volume structure. */
@@ -2940,6 +2969,7 @@ static int ntfs_fill_super(struct super_block *sb, void *opt, const int silent)
2940 mutex_unlock(&ntfs_lock); 2969 mutex_unlock(&ntfs_lock);
2941 sb->s_export_op = &ntfs_export_ops; 2970 sb->s_export_op = &ntfs_export_ops;
2942 lock_kernel(); 2971 lock_kernel();
2972 lockdep_on();
2943 return 0; 2973 return 0;
2944 } 2974 }
2945 ntfs_error(sb, "Failed to allocate root directory."); 2975 ntfs_error(sb, "Failed to allocate root directory.");
@@ -3059,6 +3089,7 @@ err_out_now:
3059 sb->s_fs_info = NULL; 3089 sb->s_fs_info = NULL;
3060 kfree(vol); 3090 kfree(vol);
3061 ntfs_debug("Failed, returning -EINVAL."); 3091 ntfs_debug("Failed, returning -EINVAL.");
3092 lockdep_on();
3062 return -EINVAL; 3093 return -EINVAL;
3063} 3094}
3064 3095
diff --git a/fs/ntfs/sysctl.h b/fs/ntfs/sysctl.h
index c8064cae8f17..beda5bf96405 100644
--- a/fs/ntfs/sysctl.h
+++ b/fs/ntfs/sysctl.h
@@ -24,7 +24,6 @@
24#ifndef _LINUX_NTFS_SYSCTL_H 24#ifndef _LINUX_NTFS_SYSCTL_H
25#define _LINUX_NTFS_SYSCTL_H 25#define _LINUX_NTFS_SYSCTL_H
26 26
27#include <linux/config.h>
28 27
29#if defined(DEBUG) && defined(CONFIG_SYSCTL) 28#if defined(DEBUG) && defined(CONFIG_SYSCTL)
30 29
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 47152bf9a7f2..f1d1c342ce01 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -558,16 +558,9 @@ static int ocfs2_direct_IO_get_blocks(struct inode *inode, sector_t iblock,
558 u64 vbo_max; /* file offset, max_blocks from iblock */ 558 u64 vbo_max; /* file offset, max_blocks from iblock */
559 u64 p_blkno; 559 u64 p_blkno;
560 int contig_blocks; 560 int contig_blocks;
561 unsigned char blocksize_bits; 561 unsigned char blocksize_bits = inode->i_sb->s_blocksize_bits;
562 unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits; 562 unsigned long max_blocks = bh_result->b_size >> inode->i_blkbits;
563 563
564 if (!inode || !bh_result) {
565 mlog(ML_ERROR, "inode or bh_result is null\n");
566 return -EIO;
567 }
568
569 blocksize_bits = inode->i_sb->s_blocksize_bits;
570
571 /* This function won't even be called if the request isn't all 564 /* This function won't even be called if the request isn't all
572 * nicely aligned and of the right size, so there's no need 565 * nicely aligned and of the right size, so there's no need
573 * for us to check any of that. */ 566 * for us to check any of that. */
@@ -666,7 +659,7 @@ out:
666 return ret; 659 return ret;
667} 660}
668 661
669struct address_space_operations ocfs2_aops = { 662const struct address_space_operations ocfs2_aops = {
670 .readpage = ocfs2_readpage, 663 .readpage = ocfs2_readpage,
671 .writepage = ocfs2_writepage, 664 .writepage = ocfs2_writepage,
672 .prepare_write = ocfs2_prepare_write, 665 .prepare_write = ocfs2_prepare_write,
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c
index 1d26cfcd9f84..504595d6cf65 100644
--- a/fs/ocfs2/cluster/heartbeat.c
+++ b/fs/ocfs2/cluster/heartbeat.c
@@ -517,6 +517,7 @@ static inline void o2hb_prepare_block(struct o2hb_region *reg,
517 hb_block->hb_seq = cpu_to_le64(cputime); 517 hb_block->hb_seq = cpu_to_le64(cputime);
518 hb_block->hb_node = node_num; 518 hb_block->hb_node = node_num;
519 hb_block->hb_generation = cpu_to_le64(generation); 519 hb_block->hb_generation = cpu_to_le64(generation);
520 hb_block->hb_dead_ms = cpu_to_le32(o2hb_dead_threshold * O2HB_REGION_TIMEOUT_MS);
520 521
521 /* This step must always happen last! */ 522 /* This step must always happen last! */
522 hb_block->hb_cksum = cpu_to_le32(o2hb_compute_block_crc_le(reg, 523 hb_block->hb_cksum = cpu_to_le32(o2hb_compute_block_crc_le(reg,
@@ -645,6 +646,8 @@ static int o2hb_check_slot(struct o2hb_region *reg,
645 struct o2nm_node *node; 646 struct o2nm_node *node;
646 struct o2hb_disk_heartbeat_block *hb_block = reg->hr_tmp_block; 647 struct o2hb_disk_heartbeat_block *hb_block = reg->hr_tmp_block;
647 u64 cputime; 648 u64 cputime;
649 unsigned int dead_ms = o2hb_dead_threshold * O2HB_REGION_TIMEOUT_MS;
650 unsigned int slot_dead_ms;
648 651
649 memcpy(hb_block, slot->ds_raw_block, reg->hr_block_bytes); 652 memcpy(hb_block, slot->ds_raw_block, reg->hr_block_bytes);
650 653
@@ -733,6 +736,23 @@ fire_callbacks:
733 &o2hb_live_slots[slot->ds_node_num]); 736 &o2hb_live_slots[slot->ds_node_num]);
734 737
735 slot->ds_equal_samples = 0; 738 slot->ds_equal_samples = 0;
739
740 /* We want to be sure that all nodes agree on the
741 * number of milliseconds before a node will be
742 * considered dead. The self-fencing timeout is
743 * computed from this value, and a discrepancy might
744 * result in heartbeat calling a node dead when it
745 * hasn't self-fenced yet. */
746 slot_dead_ms = le32_to_cpu(hb_block->hb_dead_ms);
747 if (slot_dead_ms && slot_dead_ms != dead_ms) {
748 /* TODO: Perhaps we can fail the region here. */
749 mlog(ML_ERROR, "Node %d on device %s has a dead count "
750 "of %u ms, but our count is %u ms.\n"
751 "Please double check your configuration values "
752 "for 'O2CB_HEARTBEAT_THRESHOLD'\n",
753 slot->ds_node_num, reg->hr_dev_name, slot_dead_ms,
754 dead_ms);
755 }
736 goto out; 756 goto out;
737 } 757 }
738 758
diff --git a/fs/ocfs2/cluster/masklog.h b/fs/ocfs2/cluster/masklog.h
index 73edad782537..a42628ba9ddf 100644
--- a/fs/ocfs2/cluster/masklog.h
+++ b/fs/ocfs2/cluster/masklog.h
@@ -123,6 +123,17 @@
123#define MLOG_MASK_PREFIX 0 123#define MLOG_MASK_PREFIX 0
124#endif 124#endif
125 125
126/*
127 * When logging is disabled, force the bit test to 0 for anything other
128 * than errors and notices, allowing gcc to remove the code completely.
129 * When enabled, allow all masks.
130 */
131#if defined(CONFIG_OCFS2_DEBUG_MASKLOG)
132#define ML_ALLOWED_BITS ~0
133#else
134#define ML_ALLOWED_BITS (ML_ERROR|ML_NOTICE)
135#endif
136
126#define MLOG_MAX_BITS 64 137#define MLOG_MAX_BITS 64
127 138
128struct mlog_bits { 139struct mlog_bits {
@@ -187,7 +198,8 @@ extern struct mlog_bits mlog_and_bits, mlog_not_bits;
187 198
188#define mlog(mask, fmt, args...) do { \ 199#define mlog(mask, fmt, args...) do { \
189 u64 __m = MLOG_MASK_PREFIX | (mask); \ 200 u64 __m = MLOG_MASK_PREFIX | (mask); \
190 if (__mlog_test_u64(__m, mlog_and_bits) && \ 201 if ((__m & ML_ALLOWED_BITS) && \
202 __mlog_test_u64(__m, mlog_and_bits) && \
191 !__mlog_test_u64(__m, mlog_not_bits)) { \ 203 !__mlog_test_u64(__m, mlog_not_bits)) { \
192 if (__m & ML_ERROR) \ 204 if (__m & ML_ERROR) \
193 __mlog_printk(KERN_ERR, "ERROR: "fmt , ##args); \ 205 __mlog_printk(KERN_ERR, "ERROR: "fmt , ##args); \
@@ -204,6 +216,7 @@ extern struct mlog_bits mlog_and_bits, mlog_not_bits;
204 mlog(ML_ERROR, "status = %lld\n", (long long)_st); \ 216 mlog(ML_ERROR, "status = %lld\n", (long long)_st); \
205} while (0) 217} while (0)
206 218
219#if defined(CONFIG_OCFS2_DEBUG_MASKLOG)
207#define mlog_entry(fmt, args...) do { \ 220#define mlog_entry(fmt, args...) do { \
208 mlog(ML_ENTRY, "ENTRY:" fmt , ##args); \ 221 mlog(ML_ENTRY, "ENTRY:" fmt , ##args); \
209} while (0) 222} while (0)
@@ -247,6 +260,13 @@ extern struct mlog_bits mlog_and_bits, mlog_not_bits;
247#define mlog_exit_void() do { \ 260#define mlog_exit_void() do { \
248 mlog(ML_EXIT, "EXIT\n"); \ 261 mlog(ML_EXIT, "EXIT\n"); \
249} while (0) 262} while (0)
263#else
264#define mlog_entry(...) do { } while (0)
265#define mlog_entry_void(...) do { } while (0)
266#define mlog_exit(...) do { } while (0)
267#define mlog_exit_ptr(...) do { } while (0)
268#define mlog_exit_void(...) do { } while (0)
269#endif /* defined(CONFIG_OCFS2_DEBUG_MASKLOG) */
250 270
251#define mlog_bug_on_msg(cond, fmt, args...) do { \ 271#define mlog_bug_on_msg(cond, fmt, args...) do { \
252 if (cond) { \ 272 if (cond) { \
diff --git a/fs/ocfs2/cluster/ocfs2_heartbeat.h b/fs/ocfs2/cluster/ocfs2_heartbeat.h
index 94096069cb43..3f4151da9709 100644
--- a/fs/ocfs2/cluster/ocfs2_heartbeat.h
+++ b/fs/ocfs2/cluster/ocfs2_heartbeat.h
@@ -32,6 +32,7 @@ struct o2hb_disk_heartbeat_block {
32 __u8 hb_pad1[3]; 32 __u8 hb_pad1[3];
33 __le32 hb_cksum; 33 __le32 hb_cksum;
34 __le64 hb_generation; 34 __le64 hb_generation;
35 __le32 hb_dead_ms;
35}; 36};
36 37
37#endif /* _OCFS2_HEARTBEAT_H */ 38#endif /* _OCFS2_HEARTBEAT_H */
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c
index 1591eb37a723..b650efa8c8be 100644
--- a/fs/ocfs2/cluster/tcp.c
+++ b/fs/ocfs2/cluster/tcp.c
@@ -396,8 +396,8 @@ static void o2net_set_nn_state(struct o2net_node *nn,
396 } 396 }
397 397
398 if (was_valid && !valid) { 398 if (was_valid && !valid) {
399 mlog(ML_NOTICE, "no longer connected to " SC_NODEF_FMT "\n", 399 printk(KERN_INFO "o2net: no longer connected to "
400 SC_NODEF_ARGS(old_sc)); 400 SC_NODEF_FMT "\n", SC_NODEF_ARGS(old_sc));
401 o2net_complete_nodes_nsw(nn); 401 o2net_complete_nodes_nsw(nn);
402 } 402 }
403 403
@@ -409,10 +409,10 @@ static void o2net_set_nn_state(struct o2net_node *nn,
409 * the only way to start connecting again is to down 409 * the only way to start connecting again is to down
410 * heartbeat and bring it back up. */ 410 * heartbeat and bring it back up. */
411 cancel_delayed_work(&nn->nn_connect_expired); 411 cancel_delayed_work(&nn->nn_connect_expired);
412 mlog(ML_NOTICE, "%s " SC_NODEF_FMT "\n", 412 printk(KERN_INFO "o2net: %s " SC_NODEF_FMT "\n",
413 o2nm_this_node() > sc->sc_node->nd_num ? 413 o2nm_this_node() > sc->sc_node->nd_num ?
414 "connected to" : "accepted connection from", 414 "connected to" : "accepted connection from",
415 SC_NODEF_ARGS(sc)); 415 SC_NODEF_ARGS(sc));
416 } 416 }
417 417
418 /* trigger the connecting worker func as long as we're not valid, 418 /* trigger the connecting worker func as long as we're not valid,
@@ -1280,7 +1280,7 @@ static void o2net_idle_timer(unsigned long data)
1280 1280
1281 do_gettimeofday(&now); 1281 do_gettimeofday(&now);
1282 1282
1283 mlog(ML_NOTICE, "connection to " SC_NODEF_FMT " has been idle for 10 " 1283 printk(KERN_INFO "o2net: connection to " SC_NODEF_FMT " has been idle for 10 "
1284 "seconds, shutting it down.\n", SC_NODEF_ARGS(sc)); 1284 "seconds, shutting it down.\n", SC_NODEF_ARGS(sc));
1285 mlog(ML_NOTICE, "here are some times that might help debug the " 1285 mlog(ML_NOTICE, "here are some times that might help debug the "
1286 "situation: (tmr %ld.%ld now %ld.%ld dr %ld.%ld adv " 1286 "situation: (tmr %ld.%ld now %ld.%ld dr %ld.%ld adv "
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index ae47f450792f..3d494d1a5f36 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -213,11 +213,9 @@ int ocfs2_find_files_on_disk(const char *name,
213 struct ocfs2_dir_entry **dirent) 213 struct ocfs2_dir_entry **dirent)
214{ 214{
215 int status = -ENOENT; 215 int status = -ENOENT;
216 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
217 216
218 mlog_entry("(osb=%p, parent=%llu, name='%.*s', blkno=%p, inode=%p)\n", 217 mlog_entry("(name=%.*s, blkno=%p, inode=%p, dirent_bh=%p, dirent=%p)\n",
219 osb, (unsigned long long)OCFS2_I(inode)->ip_blkno, 218 namelen, name, blkno, inode, dirent_bh, dirent);
220 namelen, name, blkno, inode);
221 219
222 *dirent_bh = ocfs2_find_entry(name, namelen, inode, dirent); 220 *dirent_bh = ocfs2_find_entry(name, namelen, inode, dirent);
223 if (!*dirent_bh || !*dirent) { 221 if (!*dirent_bh || !*dirent) {
diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h
index 9bdc9cf65991..14530ee7e11d 100644
--- a/fs/ocfs2/dlm/dlmcommon.h
+++ b/fs/ocfs2/dlm/dlmcommon.h
@@ -822,8 +822,6 @@ int dlm_begin_reco_handler(struct o2net_msg *msg, u32 len, void *data);
822int dlm_finalize_reco_handler(struct o2net_msg *msg, u32 len, void *data); 822int dlm_finalize_reco_handler(struct o2net_msg *msg, u32 len, void *data);
823int dlm_do_master_requery(struct dlm_ctxt *dlm, struct dlm_lock_resource *res, 823int dlm_do_master_requery(struct dlm_ctxt *dlm, struct dlm_lock_resource *res,
824 u8 nodenum, u8 *real_master); 824 u8 nodenum, u8 *real_master);
825int dlm_lockres_master_requery(struct dlm_ctxt *dlm,
826 struct dlm_lock_resource *res, u8 *real_master);
827 825
828 826
829int dlm_dispatch_assert_master(struct dlm_ctxt *dlm, 827int dlm_dispatch_assert_master(struct dlm_ctxt *dlm,
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c
index b8c23f7ba67e..8d1065f8b3bd 100644
--- a/fs/ocfs2/dlm/dlmdomain.c
+++ b/fs/ocfs2/dlm/dlmdomain.c
@@ -408,12 +408,13 @@ static void __dlm_print_nodes(struct dlm_ctxt *dlm)
408 408
409 assert_spin_locked(&dlm->spinlock); 409 assert_spin_locked(&dlm->spinlock);
410 410
411 mlog(ML_NOTICE, "Nodes in my domain (\"%s\"):\n", dlm->name); 411 printk(KERN_INFO "ocfs2_dlm: Nodes in domain (\"%s\"): ", dlm->name);
412 412
413 while ((node = find_next_bit(dlm->domain_map, O2NM_MAX_NODES, 413 while ((node = find_next_bit(dlm->domain_map, O2NM_MAX_NODES,
414 node + 1)) < O2NM_MAX_NODES) { 414 node + 1)) < O2NM_MAX_NODES) {
415 mlog(ML_NOTICE, " node %d\n", node); 415 printk("%d ", node);
416 } 416 }
417 printk("\n");
417} 418}
418 419
419static int dlm_exit_domain_handler(struct o2net_msg *msg, u32 len, void *data) 420static int dlm_exit_domain_handler(struct o2net_msg *msg, u32 len, void *data)
@@ -429,7 +430,7 @@ static int dlm_exit_domain_handler(struct o2net_msg *msg, u32 len, void *data)
429 430
430 node = exit_msg->node_idx; 431 node = exit_msg->node_idx;
431 432
432 mlog(0, "Node %u leaves domain %s\n", node, dlm->name); 433 printk(KERN_INFO "ocfs2_dlm: Node %u leaves domain %s\n", node, dlm->name);
433 434
434 spin_lock(&dlm->spinlock); 435 spin_lock(&dlm->spinlock);
435 clear_bit(node, dlm->domain_map); 436 clear_bit(node, dlm->domain_map);
@@ -678,6 +679,8 @@ static int dlm_assert_joined_handler(struct o2net_msg *msg, u32 len, void *data)
678 set_bit(assert->node_idx, dlm->domain_map); 679 set_bit(assert->node_idx, dlm->domain_map);
679 __dlm_set_joining_node(dlm, DLM_LOCK_RES_OWNER_UNKNOWN); 680 __dlm_set_joining_node(dlm, DLM_LOCK_RES_OWNER_UNKNOWN);
680 681
682 printk(KERN_INFO "ocfs2_dlm: Node %u joins domain %s\n",
683 assert->node_idx, dlm->name);
681 __dlm_print_nodes(dlm); 684 __dlm_print_nodes(dlm);
682 685
683 /* notify anything attached to the heartbeat events */ 686 /* notify anything attached to the heartbeat events */
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c
index 29b2845f370d..594745fab0b5 100644
--- a/fs/ocfs2/dlm/dlmrecovery.c
+++ b/fs/ocfs2/dlm/dlmrecovery.c
@@ -95,6 +95,9 @@ static void dlm_reco_unlock_ast(void *astdata, enum dlm_status st);
95static void dlm_request_all_locks_worker(struct dlm_work_item *item, 95static void dlm_request_all_locks_worker(struct dlm_work_item *item,
96 void *data); 96 void *data);
97static void dlm_mig_lockres_worker(struct dlm_work_item *item, void *data); 97static void dlm_mig_lockres_worker(struct dlm_work_item *item, void *data);
98static int dlm_lockres_master_requery(struct dlm_ctxt *dlm,
99 struct dlm_lock_resource *res,
100 u8 *real_master);
98 101
99static u64 dlm_get_next_mig_cookie(void); 102static u64 dlm_get_next_mig_cookie(void);
100 103
@@ -1484,8 +1487,9 @@ leave:
1484 1487
1485 1488
1486 1489
1487int dlm_lockres_master_requery(struct dlm_ctxt *dlm, 1490static int dlm_lockres_master_requery(struct dlm_ctxt *dlm,
1488 struct dlm_lock_resource *res, u8 *real_master) 1491 struct dlm_lock_resource *res,
1492 u8 *real_master)
1489{ 1493{
1490 struct dlm_node_iter iter; 1494 struct dlm_node_iter iter;
1491 int nodenum; 1495 int nodenum;
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 4acd37286bdd..762eb1fbb34d 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -2071,8 +2071,7 @@ int ocfs2_dlm_init(struct ocfs2_super *osb)
2071 } 2071 }
2072 2072
2073 /* launch vote thread */ 2073 /* launch vote thread */
2074 osb->vote_task = kthread_run(ocfs2_vote_thread, osb, "ocfs2vote-%d", 2074 osb->vote_task = kthread_run(ocfs2_vote_thread, osb, "ocfs2vote");
2075 osb->osb_id);
2076 if (IS_ERR(osb->vote_task)) { 2075 if (IS_ERR(osb->vote_task)) {
2077 status = PTR_ERR(osb->vote_task); 2076 status = PTR_ERR(osb->vote_task);
2078 osb->vote_task = NULL; 2077 osb->vote_task = NULL;
diff --git a/fs/ocfs2/extent_map.c b/fs/ocfs2/extent_map.c
index 1a5c69071df6..fcd4475d1f89 100644
--- a/fs/ocfs2/extent_map.c
+++ b/fs/ocfs2/extent_map.c
@@ -298,7 +298,7 @@ static int ocfs2_extent_map_find_leaf(struct inode *inode,
298 298
299 ret = ocfs2_extent_map_insert(inode, rec, 299 ret = ocfs2_extent_map_insert(inode, rec,
300 le16_to_cpu(el->l_tree_depth)); 300 le16_to_cpu(el->l_tree_depth));
301 if (ret) { 301 if (ret && (ret != -EEXIST)) {
302 mlog_errno(ret); 302 mlog_errno(ret);
303 goto out_free; 303 goto out_free;
304 } 304 }
@@ -427,6 +427,11 @@ static int ocfs2_extent_map_insert_entry(struct ocfs2_extent_map *em,
427/* 427/*
428 * Simple rule: on any return code other than -EAGAIN, anything left 428 * Simple rule: on any return code other than -EAGAIN, anything left
429 * in the insert_context will be freed. 429 * in the insert_context will be freed.
430 *
431 * Simple rule #2: A return code of -EEXIST from this function or
432 * its calls to ocfs2_extent_map_insert_entry() signifies that another
433 * thread beat us to the insert. It is not an actual error, but it
434 * tells the caller we have no more work to do.
430 */ 435 */
431static int ocfs2_extent_map_try_insert(struct inode *inode, 436static int ocfs2_extent_map_try_insert(struct inode *inode,
432 struct ocfs2_extent_rec *rec, 437 struct ocfs2_extent_rec *rec,
@@ -448,22 +453,32 @@ static int ocfs2_extent_map_try_insert(struct inode *inode,
448 goto out_unlock; 453 goto out_unlock;
449 } 454 }
450 455
456 /* Since insert_entry failed, the map MUST have old_ent */
451 old_ent = ocfs2_extent_map_lookup(em, le32_to_cpu(rec->e_cpos), 457 old_ent = ocfs2_extent_map_lookup(em, le32_to_cpu(rec->e_cpos),
452 le32_to_cpu(rec->e_clusters), NULL, 458 le32_to_cpu(rec->e_clusters),
453 NULL); 459 NULL, NULL);
454 460
455 BUG_ON(!old_ent); 461 BUG_ON(!old_ent);
456 462
457 ret = -EEXIST; 463 if (old_ent->e_tree_depth < tree_depth) {
458 if (old_ent->e_tree_depth < tree_depth) 464 /* Another thread beat us to the lower tree_depth */
465 ret = -EEXIST;
459 goto out_unlock; 466 goto out_unlock;
467 }
460 468
461 if (old_ent->e_tree_depth == tree_depth) { 469 if (old_ent->e_tree_depth == tree_depth) {
470 /*
471 * Another thread beat us to this tree_depth.
472 * Let's make sure we agree with that thread (the
473 * extent_rec should be identical).
474 */
462 if (!memcmp(rec, &old_ent->e_rec, 475 if (!memcmp(rec, &old_ent->e_rec,
463 sizeof(struct ocfs2_extent_rec))) 476 sizeof(struct ocfs2_extent_rec)))
464 ret = 0; 477 ret = 0;
478 else
479 /* FIXME: Should this be ESRCH/EBADR??? */
480 ret = -EEXIST;
465 481
466 /* FIXME: Should this be ESRCH/EBADR??? */
467 goto out_unlock; 482 goto out_unlock;
468 } 483 }
469 484
@@ -599,7 +614,7 @@ static int ocfs2_extent_map_insert(struct inode *inode,
599 tree_depth, &ctxt); 614 tree_depth, &ctxt);
600 } while (ret == -EAGAIN); 615 } while (ret == -EAGAIN);
601 616
602 if (ret < 0) 617 if ((ret < 0) && (ret != -EEXIST))
603 mlog_errno(ret); 618 mlog_errno(ret);
604 619
605 if (ctxt.left_ent) 620 if (ctxt.left_ent)
diff --git a/fs/ocfs2/inode.h b/fs/ocfs2/inode.h
index 84c507961287..35140f6cf840 100644
--- a/fs/ocfs2/inode.h
+++ b/fs/ocfs2/inode.h
@@ -114,7 +114,7 @@ static inline struct ocfs2_inode_info *OCFS2_I(struct inode *inode)
114 114
115extern kmem_cache_t *ocfs2_inode_cache; 115extern kmem_cache_t *ocfs2_inode_cache;
116 116
117extern struct address_space_operations ocfs2_aops; 117extern const struct address_space_operations ocfs2_aops;
118 118
119struct buffer_head *ocfs2_bread(struct inode *inode, int block, 119struct buffer_head *ocfs2_bread(struct inode *inode, int block,
120 int *err, int reada); 120 int *err, int reada);
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
index 910a601b2e98..f92bf1dd379a 100644
--- a/fs/ocfs2/journal.c
+++ b/fs/ocfs2/journal.c
@@ -784,8 +784,7 @@ int ocfs2_journal_load(struct ocfs2_journal *journal)
784 } 784 }
785 785
786 /* Launch the commit thread */ 786 /* Launch the commit thread */
787 osb->commit_task = kthread_run(ocfs2_commit_thread, osb, "ocfs2cmt-%d", 787 osb->commit_task = kthread_run(ocfs2_commit_thread, osb, "ocfs2cmt");
788 osb->osb_id);
789 if (IS_ERR(osb->commit_task)) { 788 if (IS_ERR(osb->commit_task)) {
790 status = PTR_ERR(osb->commit_task); 789 status = PTR_ERR(osb->commit_task);
791 osb->commit_task = NULL; 790 osb->commit_task = NULL;
@@ -1118,7 +1117,7 @@ void ocfs2_recovery_thread(struct ocfs2_super *osb, int node_num)
1118 goto out; 1117 goto out;
1119 1118
1120 osb->recovery_thread_task = kthread_run(__ocfs2_recovery_thread, osb, 1119 osb->recovery_thread_task = kthread_run(__ocfs2_recovery_thread, osb,
1121 "ocfs2rec-%d", osb->osb_id); 1120 "ocfs2rec");
1122 if (IS_ERR(osb->recovery_thread_task)) { 1121 if (IS_ERR(osb->recovery_thread_task)) {
1123 mlog_errno((int)PTR_ERR(osb->recovery_thread_task)); 1122 mlog_errno((int)PTR_ERR(osb->recovery_thread_task));
1124 osb->recovery_thread_task = NULL; 1123 osb->recovery_thread_task = NULL;
diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c
index 843cf9ddefe8..83934e33e5b0 100644
--- a/fs/ocfs2/mmap.c
+++ b/fs/ocfs2/mmap.c
@@ -46,12 +46,12 @@ static struct page *ocfs2_nopage(struct vm_area_struct * area,
46 unsigned long address, 46 unsigned long address,
47 int *type) 47 int *type)
48{ 48{
49 struct inode *inode = area->vm_file->f_dentry->d_inode;
50 struct page *page = NOPAGE_SIGBUS; 49 struct page *page = NOPAGE_SIGBUS;
51 sigset_t blocked, oldset; 50 sigset_t blocked, oldset;
52 int ret; 51 int ret;
53 52
54 mlog_entry("(inode %lu, address %lu)\n", inode->i_ino, address); 53 mlog_entry("(area=%p, address=%lu, type=%p)\n", area, address,
54 type);
55 55
56 /* The best way to deal with signals in this path is 56 /* The best way to deal with signals in this path is
57 * to block them upfront, rather than allowing the 57 * to block them upfront, rather than allowing the
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
index da1093039c01..cd4a6f253d13 100644
--- a/fs/ocfs2/ocfs2.h
+++ b/fs/ocfs2/ocfs2.h
@@ -184,7 +184,6 @@ struct ocfs2_journal;
184struct ocfs2_journal_handle; 184struct ocfs2_journal_handle;
185struct ocfs2_super 185struct ocfs2_super
186{ 186{
187 u32 osb_id; /* id used by the proc interface */
188 struct task_struct *commit_task; 187 struct task_struct *commit_task;
189 struct super_block *sb; 188 struct super_block *sb;
190 struct inode *root_inode; 189 struct inode *root_inode;
@@ -222,13 +221,11 @@ struct ocfs2_super
222 unsigned long s_mount_opt; 221 unsigned long s_mount_opt;
223 222
224 u16 max_slots; 223 u16 max_slots;
225 u16 num_nodes;
226 s16 node_num; 224 s16 node_num;
227 s16 slot_num; 225 s16 slot_num;
228 int s_sectsize_bits; 226 int s_sectsize_bits;
229 int s_clustersize; 227 int s_clustersize;
230 int s_clustersize_bits; 228 int s_clustersize_bits;
231 struct proc_dir_entry *proc_sub_dir; /* points to /proc/fs/ocfs2/<maj_min> */
232 229
233 atomic_t vol_state; 230 atomic_t vol_state;
234 struct mutex recovery_lock; 231 struct mutex recovery_lock;
@@ -294,7 +291,6 @@ struct ocfs2_super
294}; 291};
295 292
296#define OCFS2_SB(sb) ((struct ocfs2_super *)(sb)->s_fs_info) 293#define OCFS2_SB(sb) ((struct ocfs2_super *)(sb)->s_fs_info)
297#define OCFS2_MAX_OSB_ID 65536
298 294
299static inline int ocfs2_should_order_data(struct inode *inode) 295static inline int ocfs2_should_order_data(struct inode *inode)
300{ 296{
diff --git a/fs/ocfs2/slot_map.c b/fs/ocfs2/slot_map.c
index 871627961d6d..aa6f5aadedc4 100644
--- a/fs/ocfs2/slot_map.c
+++ b/fs/ocfs2/slot_map.c
@@ -264,7 +264,7 @@ int ocfs2_find_slot(struct ocfs2_super *osb)
264 osb->slot_num = slot; 264 osb->slot_num = slot;
265 spin_unlock(&si->si_lock); 265 spin_unlock(&si->si_lock);
266 266
267 mlog(ML_NOTICE, "taking node slot %d\n", osb->slot_num); 267 mlog(0, "taking node slot %d\n", osb->slot_num);
268 268
269 status = ocfs2_update_disk_slots(osb, si); 269 status = ocfs2_update_disk_slots(osb, si);
270 if (status < 0) 270 if (status < 0)
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index cdf73393f094..382706a67ffd 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -68,13 +68,6 @@
68 68
69#include "buffer_head_io.h" 69#include "buffer_head_io.h"
70 70
71/*
72 * Globals
73 */
74static spinlock_t ocfs2_globals_lock = SPIN_LOCK_UNLOCKED;
75
76static u32 osb_id; /* Keeps track of next available OSB Id */
77
78static kmem_cache_t *ocfs2_inode_cachep = NULL; 71static kmem_cache_t *ocfs2_inode_cachep = NULL;
79 72
80kmem_cache_t *ocfs2_lock_cache = NULL; 73kmem_cache_t *ocfs2_lock_cache = NULL;
@@ -642,10 +635,9 @@ static int ocfs2_fill_super(struct super_block *sb, void *data, int silent)
642 635
643 ocfs2_complete_mount_recovery(osb); 636 ocfs2_complete_mount_recovery(osb);
644 637
645 printk("ocfs2: Mounting device (%u,%u) on (node %d, slot %d) with %s " 638 printk(KERN_INFO "ocfs2: Mounting device (%s) on (node %d, slot %d) "
646 "data mode.\n", 639 "with %s data mode.\n",
647 MAJOR(sb->s_dev), MINOR(sb->s_dev), osb->node_num, 640 osb->dev_str, osb->node_num, osb->slot_num,
648 osb->slot_num,
649 osb->s_mount_opt & OCFS2_MOUNT_DATA_WRITEBACK ? "writeback" : 641 osb->s_mount_opt & OCFS2_MOUNT_DATA_WRITEBACK ? "writeback" :
650 "ordered"); 642 "ordered");
651 643
@@ -800,10 +792,6 @@ static int __init ocfs2_init(void)
800 goto leave; 792 goto leave;
801 } 793 }
802 794
803 spin_lock(&ocfs2_globals_lock);
804 osb_id = 0;
805 spin_unlock(&ocfs2_globals_lock);
806
807 ocfs2_debugfs_root = debugfs_create_dir("ocfs2", NULL); 795 ocfs2_debugfs_root = debugfs_create_dir("ocfs2", NULL);
808 if (!ocfs2_debugfs_root) { 796 if (!ocfs2_debugfs_root) {
809 status = -EFAULT; 797 status = -EFAULT;
@@ -1020,7 +1008,7 @@ static int ocfs2_fill_local_node_info(struct ocfs2_super *osb)
1020 goto bail; 1008 goto bail;
1021 } 1009 }
1022 1010
1023 mlog(ML_NOTICE, "I am node %d\n", osb->node_num); 1011 mlog(0, "I am node %d\n", osb->node_num);
1024 1012
1025 status = 0; 1013 status = 0;
1026bail: 1014bail:
@@ -1191,8 +1179,8 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err)
1191 1179
1192 atomic_set(&osb->vol_state, VOLUME_DISMOUNTED); 1180 atomic_set(&osb->vol_state, VOLUME_DISMOUNTED);
1193 1181
1194 printk("ocfs2: Unmounting device (%u,%u) on (node %d)\n", 1182 printk(KERN_INFO "ocfs2: Unmounting device (%s) on (node %d)\n",
1195 MAJOR(osb->sb->s_dev), MINOR(osb->sb->s_dev), osb->node_num); 1183 osb->dev_str, osb->node_num);
1196 1184
1197 ocfs2_delete_osb(osb); 1185 ocfs2_delete_osb(osb);
1198 kfree(osb); 1186 kfree(osb);
@@ -1212,8 +1200,6 @@ static int ocfs2_setup_osb_uuid(struct ocfs2_super *osb, const unsigned char *uu
1212 if (osb->uuid_str == NULL) 1200 if (osb->uuid_str == NULL)
1213 return -ENOMEM; 1201 return -ENOMEM;
1214 1202
1215 memcpy(osb->uuid, uuid, OCFS2_VOL_UUID_LEN);
1216
1217 for (i = 0, ptr = osb->uuid_str; i < OCFS2_VOL_UUID_LEN; i++) { 1203 for (i = 0, ptr = osb->uuid_str; i < OCFS2_VOL_UUID_LEN; i++) {
1218 /* print with null */ 1204 /* print with null */
1219 ret = snprintf(ptr, 3, "%02X", uuid[i]); 1205 ret = snprintf(ptr, 3, "%02X", uuid[i]);
@@ -1311,13 +1297,6 @@ static int ocfs2_initialize_super(struct super_block *sb,
1311 goto bail; 1297 goto bail;
1312 } 1298 }
1313 1299
1314 osb->uuid = kmalloc(OCFS2_VOL_UUID_LEN, GFP_KERNEL);
1315 if (!osb->uuid) {
1316 mlog(ML_ERROR, "unable to alloc uuid\n");
1317 status = -ENOMEM;
1318 goto bail;
1319 }
1320
1321 di = (struct ocfs2_dinode *)bh->b_data; 1300 di = (struct ocfs2_dinode *)bh->b_data;
1322 1301
1323 osb->max_slots = le16_to_cpu(di->id2.i_super.s_max_slots); 1302 osb->max_slots = le16_to_cpu(di->id2.i_super.s_max_slots);
@@ -1327,7 +1306,7 @@ static int ocfs2_initialize_super(struct super_block *sb,
1327 status = -EINVAL; 1306 status = -EINVAL;
1328 goto bail; 1307 goto bail;
1329 } 1308 }
1330 mlog(ML_NOTICE, "max_slots for this device: %u\n", osb->max_slots); 1309 mlog(0, "max_slots for this device: %u\n", osb->max_slots);
1331 1310
1332 init_waitqueue_head(&osb->osb_wipe_event); 1311 init_waitqueue_head(&osb->osb_wipe_event);
1333 osb->osb_orphan_wipes = kcalloc(osb->max_slots, 1312 osb->osb_orphan_wipes = kcalloc(osb->max_slots,
@@ -1418,7 +1397,7 @@ static int ocfs2_initialize_super(struct super_block *sb,
1418 goto bail; 1397 goto bail;
1419 } 1398 }
1420 1399
1421 memcpy(&uuid_net_key, &osb->uuid[i], sizeof(osb->net_key)); 1400 memcpy(&uuid_net_key, di->id2.i_super.s_uuid, sizeof(uuid_net_key));
1422 osb->net_key = le32_to_cpu(uuid_net_key); 1401 osb->net_key = le32_to_cpu(uuid_net_key);
1423 1402
1424 strncpy(osb->vol_label, di->id2.i_super.s_label, 63); 1403 strncpy(osb->vol_label, di->id2.i_super.s_label, 63);
@@ -1484,18 +1463,6 @@ static int ocfs2_initialize_super(struct super_block *sb,
1484 goto bail; 1463 goto bail;
1485 } 1464 }
1486 1465
1487 /* Link this osb onto the global linked list of all osb structures. */
1488 /* The Global Link List is mainted for the whole driver . */
1489 spin_lock(&ocfs2_globals_lock);
1490 osb->osb_id = osb_id;
1491 if (osb_id < OCFS2_MAX_OSB_ID)
1492 osb_id++;
1493 else {
1494 mlog(ML_ERROR, "Too many volumes mounted\n");
1495 status = -ENOMEM;
1496 }
1497 spin_unlock(&ocfs2_globals_lock);
1498
1499bail: 1466bail:
1500 mlog_exit(status); 1467 mlog_exit(status);
1501 return status; 1468 return status;
diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c
index 0c8a1294ec96..c0f68aa6c175 100644
--- a/fs/ocfs2/symlink.c
+++ b/fs/ocfs2/symlink.c
@@ -154,7 +154,7 @@ static void *ocfs2_follow_link(struct dentry *dentry,
154 } 154 }
155 155
156 status = vfs_follow_link(nd, link); 156 status = vfs_follow_link(nd, link);
157 if (status) 157 if (status && status != -ENOENT)
158 mlog_errno(status); 158 mlog_errno(status);
159bail: 159bail:
160 if (page) { 160 if (page) {
diff --git a/fs/partitions/Makefile b/fs/partitions/Makefile
index 42c7d3878ed0..d713ce6b3e12 100644
--- a/fs/partitions/Makefile
+++ b/fs/partitions/Makefile
@@ -4,7 +4,6 @@
4 4
5obj-y := check.o 5obj-y := check.o
6 6
7obj-$(CONFIG_DEVFS_FS) += devfs.o
8obj-$(CONFIG_ACORN_PARTITION) += acorn.o 7obj-$(CONFIG_ACORN_PARTITION) += acorn.o
9obj-$(CONFIG_AMIGA_PARTITION) += amiga.o 8obj-$(CONFIG_AMIGA_PARTITION) += amiga.o
10obj-$(CONFIG_ATARI_PARTITION) += atari.o 9obj-$(CONFIG_ATARI_PARTITION) += atari.o
diff --git a/fs/partitions/acorn.c b/fs/partitions/acorn.c
index c05085710fce..1bc9f372c7d4 100644
--- a/fs/partitions/acorn.c
+++ b/fs/partitions/acorn.c
@@ -12,7 +12,6 @@
12 * every single manufacturer of SCSI and IDE cards created their own 12 * every single manufacturer of SCSI and IDE cards created their own
13 * method. 13 * method.
14 */ 14 */
15#include <linux/config.h>
16#include <linux/buffer_head.h> 15#include <linux/buffer_head.h>
17#include <linux/adfs_fs.h> 16#include <linux/adfs_fs.h>
18 17
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 2ef313a96b66..51c6a748df49 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -18,10 +18,8 @@
18#include <linux/fs.h> 18#include <linux/fs.h>
19#include <linux/kmod.h> 19#include <linux/kmod.h>
20#include <linux/ctype.h> 20#include <linux/ctype.h>
21#include <linux/devfs_fs_kernel.h>
22 21
23#include "check.h" 22#include "check.h"
24#include "devfs.h"
25 23
26#include "acorn.h" 24#include "acorn.h"
27#include "amiga.h" 25#include "amiga.h"
@@ -161,18 +159,11 @@ check_partition(struct gendisk *hd, struct block_device *bdev)
161 if (!state) 159 if (!state)
162 return NULL; 160 return NULL;
163 161
164#ifdef CONFIG_DEVFS_FS 162 disk_name(hd, 0, state->name);
165 if (hd->devfs_name[0] != '\0') { 163 printk(KERN_INFO " %s:", state->name);
166 printk(KERN_INFO " /dev/%s:", hd->devfs_name); 164 if (isdigit(state->name[strlen(state->name)-1]))
167 sprintf(state->name, "p"); 165 sprintf(state->name, "p");
168 } 166
169#endif
170 else {
171 disk_name(hd, 0, state->name);
172 printk(KERN_INFO " %s:", state->name);
173 if (isdigit(state->name[strlen(state->name)-1]))
174 sprintf(state->name, "p");
175 }
176 state->limit = hd->minors; 167 state->limit = hd->minors;
177 i = res = 0; 168 i = res = 0;
178 while (!res && check_part[i]) { 169 while (!res && check_part[i]) {
@@ -328,7 +319,6 @@ void delete_partition(struct gendisk *disk, int part)
328 p->nr_sects = 0; 319 p->nr_sects = 0;
329 p->ios[0] = p->ios[1] = 0; 320 p->ios[0] = p->ios[1] = 0;
330 p->sectors[0] = p->sectors[1] = 0; 321 p->sectors[0] = p->sectors[1] = 0;
331 devfs_remove("%s/part%d", disk->devfs_name, part);
332 sysfs_remove_link(&p->kobj, "subsystem"); 322 sysfs_remove_link(&p->kobj, "subsystem");
333 if (p->holder_dir) 323 if (p->holder_dir)
334 kobject_unregister(p->holder_dir); 324 kobject_unregister(p->holder_dir);
@@ -349,10 +339,7 @@ void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len)
349 p->start_sect = start; 339 p->start_sect = start;
350 p->nr_sects = len; 340 p->nr_sects = len;
351 p->partno = part; 341 p->partno = part;
352 342 p->policy = disk->policy;
353 devfs_mk_bdev(MKDEV(disk->major, disk->first_minor + part),
354 S_IFBLK|S_IRUSR|S_IWUSR,
355 "%s/part%d", disk->devfs_name, part);
356 343
357 if (isdigit(disk->kobj.name[strlen(disk->kobj.name)-1])) 344 if (isdigit(disk->kobj.name[strlen(disk->kobj.name)-1]))
358 snprintf(p->kobj.name,KOBJ_NAME_LEN,"%sp%d",disk->kobj.name,part); 345 snprintf(p->kobj.name,KOBJ_NAME_LEN,"%sp%d",disk->kobj.name,part);
@@ -423,14 +410,8 @@ void register_disk(struct gendisk *disk)
423 disk_sysfs_add_subdirs(disk); 410 disk_sysfs_add_subdirs(disk);
424 411
425 /* No minors to use for partitions */ 412 /* No minors to use for partitions */
426 if (disk->minors == 1) { 413 if (disk->minors == 1)
427 if (disk->devfs_name[0] != '\0')
428 devfs_add_disk(disk);
429 goto exit; 414 goto exit;
430 }
431
432 /* always add handle for the whole disk */
433 devfs_add_partitioned(disk);
434 415
435 /* No such device (e.g., media were just removed) */ 416 /* No such device (e.g., media were just removed) */
436 if (!get_capacity(disk)) 417 if (!get_capacity(disk))
@@ -538,8 +519,6 @@ void del_gendisk(struct gendisk *disk)
538 disk_stat_set_all(disk, 0); 519 disk_stat_set_all(disk, 0);
539 disk->stamp = 0; 520 disk->stamp = 0;
540 521
541 devfs_remove_disk(disk);
542
543 kobject_uevent(&disk->kobj, KOBJ_REMOVE); 522 kobject_uevent(&disk->kobj, KOBJ_REMOVE);
544 if (disk->holder_dir) 523 if (disk->holder_dir)
545 kobject_unregister(disk->holder_dir); 524 kobject_unregister(disk->holder_dir);
diff --git a/fs/partitions/devfs.c b/fs/partitions/devfs.c
deleted file mode 100644
index 3f0a780c9cec..000000000000
--- a/fs/partitions/devfs.c
+++ /dev/null
@@ -1,130 +0,0 @@
1/*
2 * This tries to keep block devices away from devfs as much as possible.
3 */
4#include <linux/fs.h>
5#include <linux/devfs_fs_kernel.h>
6#include <linux/vmalloc.h>
7#include <linux/genhd.h>
8#include <linux/bitops.h>
9#include <linux/mutex.h>
10
11
12struct unique_numspace {
13 u32 num_free; /* Num free in bits */
14 u32 length; /* Array length in bytes */
15 unsigned long *bits;
16 struct semaphore mutex;
17};
18
19static DEFINE_MUTEX(numspace_mutex);
20
21static int expand_numspace(struct unique_numspace *s)
22{
23 u32 length;
24 void *bits;
25
26 if (s->length < 16)
27 length = 16;
28 else
29 length = s->length << 1;
30
31 bits = vmalloc(length);
32 if (!bits)
33 return -ENOMEM;
34 if (s->bits) {
35 memcpy(bits, s->bits, s->length);
36 vfree(s->bits);
37 }
38
39 s->num_free = (length - s->length) << 3;
40 s->bits = bits;
41 memset(bits + s->length, 0, length - s->length);
42 s->length = length;
43
44 return 0;
45}
46
47static int alloc_unique_number(struct unique_numspace *s)
48{
49 int rval = 0;
50
51 mutex_lock(&numspace_mutex);
52 if (s->num_free < 1)
53 rval = expand_numspace(s);
54 if (!rval) {
55 rval = find_first_zero_bit(s->bits, s->length << 3);
56 --s->num_free;
57 __set_bit(rval, s->bits);
58 }
59 mutex_unlock(&numspace_mutex);
60
61 return rval;
62}
63
64static void dealloc_unique_number(struct unique_numspace *s, int number)
65{
66 int old_val;
67
68 if (number >= 0) {
69 mutex_lock(&numspace_mutex);
70 old_val = __test_and_clear_bit(number, s->bits);
71 if (old_val)
72 ++s->num_free;
73 mutex_unlock(&numspace_mutex);
74 }
75}
76
77static struct unique_numspace disc_numspace;
78static struct unique_numspace cdrom_numspace;
79
80void devfs_add_partitioned(struct gendisk *disk)
81{
82 char dirname[64], symlink[16];
83
84 devfs_mk_dir(disk->devfs_name);
85 devfs_mk_bdev(MKDEV(disk->major, disk->first_minor),
86 S_IFBLK|S_IRUSR|S_IWUSR,
87 "%s/disc", disk->devfs_name);
88
89 disk->number = alloc_unique_number(&disc_numspace);
90
91 sprintf(symlink, "discs/disc%d", disk->number);
92 sprintf(dirname, "../%s", disk->devfs_name);
93 devfs_mk_symlink(symlink, dirname);
94
95}
96
97void devfs_add_disk(struct gendisk *disk)
98{
99 devfs_mk_bdev(MKDEV(disk->major, disk->first_minor),
100 (disk->flags & GENHD_FL_CD) ?
101 S_IFBLK|S_IRUGO|S_IWUGO :
102 S_IFBLK|S_IRUSR|S_IWUSR,
103 "%s", disk->devfs_name);
104
105 if (disk->flags & GENHD_FL_CD) {
106 char dirname[64], symlink[16];
107
108 disk->number = alloc_unique_number(&cdrom_numspace);
109
110 sprintf(symlink, "cdroms/cdrom%d", disk->number);
111 sprintf(dirname, "../%s", disk->devfs_name);
112 devfs_mk_symlink(symlink, dirname);
113 }
114}
115
116void devfs_remove_disk(struct gendisk *disk)
117{
118 if (disk->minors != 1) {
119 devfs_remove("discs/disc%d", disk->number);
120 dealloc_unique_number(&disc_numspace, disk->number);
121 devfs_remove("%s/disc", disk->devfs_name);
122 }
123 if (disk->flags & GENHD_FL_CD) {
124 devfs_remove("cdroms/cdrom%d", disk->number);
125 dealloc_unique_number(&cdrom_numspace, disk->number);
126 }
127 devfs_remove(disk->devfs_name);
128}
129
130
diff --git a/fs/partitions/devfs.h b/fs/partitions/devfs.h
deleted file mode 100644
index 176118b4e492..000000000000
--- a/fs/partitions/devfs.h
+++ /dev/null
@@ -1,10 +0,0 @@
1
2#ifdef CONFIG_DEVFS_FS
3void devfs_add_disk(struct gendisk *dev);
4void devfs_add_partitioned(struct gendisk *dev);
5void devfs_remove_disk(struct gendisk *dev);
6#else
7# define devfs_add_disk(disk) do { } while (0)
8# define devfs_add_partitioned(disk) do { } while (0)
9# define devfs_remove_disk(disk) do { } while (0)
10#endif
diff --git a/fs/partitions/efi.c b/fs/partitions/efi.c
index 0f5b017aebad..63730282ad81 100644
--- a/fs/partitions/efi.c
+++ b/fs/partitions/efi.c
@@ -91,7 +91,6 @@
91 * - Code works, detects all the partitions. 91 * - Code works, detects all the partitions.
92 * 92 *
93 ************************************************************/ 93 ************************************************************/
94#include <linux/config.h>
95#include <linux/crc32.h> 94#include <linux/crc32.h>
96#include "check.h" 95#include "check.h"
97#include "efi.h" 96#include "efi.h"
diff --git a/fs/partitions/efi.h b/fs/partitions/efi.h
index c44fb0561448..2cc89d0475bf 100644
--- a/fs/partitions/efi.h
+++ b/fs/partitions/efi.h
@@ -26,7 +26,6 @@
26#define FS_PART_EFI_H_INCLUDED 26#define FS_PART_EFI_H_INCLUDED
27 27
28#include <linux/types.h> 28#include <linux/types.h>
29#include <linux/config.h>
30#include <linux/fs.h> 29#include <linux/fs.h>
31#include <linux/genhd.h> 30#include <linux/genhd.h>
32#include <linux/kernel.h> 31#include <linux/kernel.h>
diff --git a/fs/partitions/ibm.c b/fs/partitions/ibm.c
index 830c55d86ab1..d352a7381fed 100644
--- a/fs/partitions/ibm.c
+++ b/fs/partitions/ibm.c
@@ -6,7 +6,6 @@
6 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 6 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
7 */ 7 */
8 8
9#include <linux/config.h>
10#include <linux/buffer_head.h> 9#include <linux/buffer_head.h>
11#include <linux/hdreg.h> 10#include <linux/hdreg.h>
12#include <linux/slab.h> 11#include <linux/slab.h>
diff --git a/fs/partitions/mac.c b/fs/partitions/mac.c
index 813292f21210..c0871002d00d 100644
--- a/fs/partitions/mac.c
+++ b/fs/partitions/mac.c
@@ -6,7 +6,6 @@
6 * Re-organised Feb 1998 Russell King 6 * Re-organised Feb 1998 Russell King
7 */ 7 */
8 8
9#include <linux/config.h>
10#include <linux/ctype.h> 9#include <linux/ctype.h>
11#include "check.h" 10#include "check.h"
12#include "mac.h" 11#include "mac.h"
diff --git a/fs/partitions/msdos.c b/fs/partitions/msdos.c
index 9935d254186e..8f12587c3129 100644
--- a/fs/partitions/msdos.c
+++ b/fs/partitions/msdos.c
@@ -19,7 +19,6 @@
19 * Re-organised Feb 1998 Russell King 19 * Re-organised Feb 1998 Russell King
20 */ 20 */
21 21
22#include <linux/config.h>
23 22
24#include "check.h" 23#include "check.h"
25#include "msdos.h" 24#include "msdos.h"
diff --git a/fs/proc/array.c b/fs/proc/array.c
index 7a76ad570230..7495d3e20775 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -52,7 +52,6 @@
52 * : base.c too. 52 * : base.c too.
53 */ 53 */
54 54
55#include <linux/config.h>
56#include <linux/types.h> 55#include <linux/types.h>
57#include <linux/errno.h> 56#include <linux/errno.h>
58#include <linux/time.h> 57#include <linux/time.h>
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 6ba7785319de..243a94af0427 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -49,7 +49,6 @@
49 49
50#include <asm/uaccess.h> 50#include <asm/uaccess.h>
51 51
52#include <linux/config.h>
53#include <linux/errno.h> 52#include <linux/errno.h>
54#include <linux/time.h> 53#include <linux/time.h>
55#include <linux/proc_fs.h> 54#include <linux/proc_fs.h>
diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c
index 17f6e8fa1397..6a984f64edd7 100644
--- a/fs/proc/kcore.c
+++ b/fs/proc/kcore.c
@@ -9,7 +9,6 @@
9 * Safe accesses to vmalloc/direct-mapped discontiguous areas, Kanoj Sarcar <kanoj@sgi.com> 9 * Safe accesses to vmalloc/direct-mapped discontiguous areas, Kanoj Sarcar <kanoj@sgi.com>
10 */ 10 */
11 11
12#include <linux/config.h>
13#include <linux/mm.h> 12#include <linux/mm.h>
14#include <linux/proc_fs.h> 13#include <linux/proc_fs.h>
15#include <linux/user.h> 14#include <linux/user.h>
@@ -43,8 +42,6 @@ const struct file_operations proc_kcore_operations = {
43#define kc_offset_to_vaddr(o) ((o) + PAGE_OFFSET) 42#define kc_offset_to_vaddr(o) ((o) + PAGE_OFFSET)
44#endif 43#endif
45 44
46#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
47
48/* An ELF note in memory */ 45/* An ELF note in memory */
49struct memelfnote 46struct memelfnote
50{ 47{
@@ -385,7 +382,7 @@ read_kcore(struct file *file, char __user *buffer, size_t buflen, loff_t *fpos)
385 */ 382 */
386 if (n) { 383 if (n) {
387 if (clear_user(buffer + tsz - n, 384 if (clear_user(buffer + tsz - n,
388 tsz - n)) 385 n))
389 return -EFAULT; 386 return -EFAULT;
390 } 387 }
391 } else { 388 } else {
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index 5c10ea157425..9f2cfc30f9cf 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -26,7 +26,6 @@
26#include <linux/mman.h> 26#include <linux/mman.h>
27#include <linux/proc_fs.h> 27#include <linux/proc_fs.h>
28#include <linux/ioport.h> 28#include <linux/ioport.h>
29#include <linux/config.h>
30#include <linux/mm.h> 29#include <linux/mm.h>
31#include <linux/mmzone.h> 30#include <linux/mmzone.h>
32#include <linux/pagemap.h> 31#include <linux/pagemap.h>
@@ -120,7 +119,6 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
120{ 119{
121 struct sysinfo i; 120 struct sysinfo i;
122 int len; 121 int len;
123 struct page_state ps;
124 unsigned long inactive; 122 unsigned long inactive;
125 unsigned long active; 123 unsigned long active;
126 unsigned long free; 124 unsigned long free;
@@ -129,7 +127,6 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
129 struct vmalloc_info vmi; 127 struct vmalloc_info vmi;
130 long cached; 128 long cached;
131 129
132 get_page_state(&ps);
133 get_zone_counts(&active, &inactive, &free); 130 get_zone_counts(&active, &inactive, &free);
134 131
135/* 132/*
@@ -142,7 +139,8 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
142 allowed = ((totalram_pages - hugetlb_total_pages()) 139 allowed = ((totalram_pages - hugetlb_total_pages())
143 * sysctl_overcommit_ratio / 100) + total_swap_pages; 140 * sysctl_overcommit_ratio / 100) + total_swap_pages;
144 141
145 cached = get_page_cache_size() - total_swapcache_pages - i.bufferram; 142 cached = global_page_state(NR_FILE_PAGES) -
143 total_swapcache_pages - i.bufferram;
146 if (cached < 0) 144 if (cached < 0)
147 cached = 0; 145 cached = 0;
148 146
@@ -167,11 +165,14 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
167 "SwapFree: %8lu kB\n" 165 "SwapFree: %8lu kB\n"
168 "Dirty: %8lu kB\n" 166 "Dirty: %8lu kB\n"
169 "Writeback: %8lu kB\n" 167 "Writeback: %8lu kB\n"
168 "AnonPages: %8lu kB\n"
170 "Mapped: %8lu kB\n" 169 "Mapped: %8lu kB\n"
171 "Slab: %8lu kB\n" 170 "Slab: %8lu kB\n"
171 "PageTables: %8lu kB\n"
172 "NFS Unstable: %8lu kB\n"
173 "Bounce: %8lu kB\n"
172 "CommitLimit: %8lu kB\n" 174 "CommitLimit: %8lu kB\n"
173 "Committed_AS: %8lu kB\n" 175 "Committed_AS: %8lu kB\n"
174 "PageTables: %8lu kB\n"
175 "VmallocTotal: %8lu kB\n" 176 "VmallocTotal: %8lu kB\n"
176 "VmallocUsed: %8lu kB\n" 177 "VmallocUsed: %8lu kB\n"
177 "VmallocChunk: %8lu kB\n", 178 "VmallocChunk: %8lu kB\n",
@@ -188,13 +189,16 @@ static int meminfo_read_proc(char *page, char **start, off_t off,
188 K(i.freeram-i.freehigh), 189 K(i.freeram-i.freehigh),
189 K(i.totalswap), 190 K(i.totalswap),
190 K(i.freeswap), 191 K(i.freeswap),
191 K(ps.nr_dirty), 192 K(global_page_state(NR_FILE_DIRTY)),
192 K(ps.nr_writeback), 193 K(global_page_state(NR_WRITEBACK)),
193 K(ps.nr_mapped), 194 K(global_page_state(NR_ANON_PAGES)),
194 K(ps.nr_slab), 195 K(global_page_state(NR_FILE_MAPPED)),
196 K(global_page_state(NR_SLAB)),
197 K(global_page_state(NR_PAGETABLE)),
198 K(global_page_state(NR_UNSTABLE_NFS)),
199 K(global_page_state(NR_BOUNCE)),
195 K(allowed), 200 K(allowed),
196 K(committed), 201 K(committed),
197 K(ps.nr_page_table_pages),
198 (unsigned long)VMALLOC_TOTAL >> 10, 202 (unsigned long)VMALLOC_TOTAL >> 10,
199 vmi.used >> 10, 203 vmi.used >> 10,
200 vmi.largest_chunk >> 10 204 vmi.largest_chunk >> 10
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 9995356ce73e..8901c65caca8 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -12,7 +12,6 @@
12#include <linux/time.h> 12#include <linux/time.h>
13#include <linux/proc_fs.h> 13#include <linux/proc_fs.h>
14#include <linux/stat.h> 14#include <linux/stat.h>
15#include <linux/config.h>
16#include <linux/init.h> 15#include <linux/init.h>
17#include <linux/module.h> 16#include <linux/module.h>
18#include <linux/bitops.h> 17#include <linux/bitops.h>
diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c
index af69f28277b6..4616ed50ffcd 100644
--- a/fs/proc/task_nommu.c
+++ b/fs/proc/task_nommu.c
@@ -107,7 +107,7 @@ int proc_exe_link(struct inode *inode, struct dentry **dentry, struct vfsmount *
107{ 107{
108 struct vm_list_struct *vml; 108 struct vm_list_struct *vml;
109 struct vm_area_struct *vma; 109 struct vm_area_struct *vma;
110 struct task_struct *task = proc_task(inode); 110 struct task_struct *task = get_proc_task(inode);
111 struct mm_struct *mm = get_task_mm(task); 111 struct mm_struct *mm = get_task_mm(task);
112 int result = -ENOENT; 112 int result = -ENOENT;
113 113
diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
index 20d4b2237fce..d96050728c43 100644
--- a/fs/proc/vmcore.c
+++ b/fs/proc/vmcore.c
@@ -7,7 +7,6 @@
7 * 7 *
8 */ 8 */
9 9
10#include <linux/config.h>
11#include <linux/mm.h> 10#include <linux/mm.h>
12#include <linux/proc_fs.h> 11#include <linux/proc_fs.h>
13#include <linux/user.h> 12#include <linux/user.h>
diff --git a/fs/qnx4/bitmap.c b/fs/qnx4/bitmap.c
index 46efbf52cbec..8425cf6e9624 100644
--- a/fs/qnx4/bitmap.c
+++ b/fs/qnx4/bitmap.c
@@ -13,7 +13,6 @@
13 * 28-06-1998 by Frank Denis : qnx4_free_inode (to be fixed) . 13 * 28-06-1998 by Frank Denis : qnx4_free_inode (to be fixed) .
14 */ 14 */
15 15
16#include <linux/config.h>
17#include <linux/time.h> 16#include <linux/time.h>
18#include <linux/fs.h> 17#include <linux/fs.h>
19#include <linux/qnx4_fs.h> 18#include <linux/qnx4_fs.h>
diff --git a/fs/qnx4/dir.c b/fs/qnx4/dir.c
index 9031948fefd0..0d7103fa0df5 100644
--- a/fs/qnx4/dir.c
+++ b/fs/qnx4/dir.c
@@ -11,7 +11,6 @@
11 * 20-06-1998 by Frank Denis : Linux 2.1.99+ & dcache support. 11 * 20-06-1998 by Frank Denis : Linux 2.1.99+ & dcache support.
12 */ 12 */
13 13
14#include <linux/config.h>
15#include <linux/string.h> 14#include <linux/string.h>
16#include <linux/errno.h> 15#include <linux/errno.h>
17#include <linux/fs.h> 16#include <linux/fs.h>
diff --git a/fs/qnx4/fsync.c b/fs/qnx4/fsync.c
index df5bc75d5414..aa3b19544bee 100644
--- a/fs/qnx4/fsync.c
+++ b/fs/qnx4/fsync.c
@@ -10,7 +10,6 @@
10 * 24-03-1998 by Richard Frowijn : first release. 10 * 24-03-1998 by Richard Frowijn : first release.
11 */ 11 */
12 12
13#include <linux/config.h>
14#include <linux/errno.h> 13#include <linux/errno.h>
15#include <linux/time.h> 14#include <linux/time.h>
16#include <linux/stat.h> 15#include <linux/stat.h>
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index 2f24c46f72a1..5a903491e697 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -12,7 +12,6 @@
12 * 30-06-1998 by Frank Denis : first step to write inodes. 12 * 30-06-1998 by Frank Denis : first step to write inodes.
13 */ 13 */
14 14
15#include <linux/config.h>
16#include <linux/module.h> 15#include <linux/module.h>
17#include <linux/types.h> 16#include <linux/types.h>
18#include <linux/string.h> 17#include <linux/string.h>
@@ -450,7 +449,7 @@ static sector_t qnx4_bmap(struct address_space *mapping, sector_t block)
450{ 449{
451 return generic_block_bmap(mapping,block,qnx4_get_block); 450 return generic_block_bmap(mapping,block,qnx4_get_block);
452} 451}
453static struct address_space_operations qnx4_aops = { 452static const struct address_space_operations qnx4_aops = {
454 .readpage = qnx4_readpage, 453 .readpage = qnx4_readpage,
455 .writepage = qnx4_writepage, 454 .writepage = qnx4_writepage,
456 .sync_page = block_sync_page, 455 .sync_page = block_sync_page,
diff --git a/fs/qnx4/namei.c b/fs/qnx4/namei.c
index 4af4951d7f54..c3d83f67154a 100644
--- a/fs/qnx4/namei.c
+++ b/fs/qnx4/namei.c
@@ -12,7 +12,6 @@
12 * 04-07-1998 by Frank Denis : first step for rmdir/unlink. 12 * 04-07-1998 by Frank Denis : first step for rmdir/unlink.
13 */ 13 */
14 14
15#include <linux/config.h>
16#include <linux/time.h> 15#include <linux/time.h>
17#include <linux/fs.h> 16#include <linux/fs.h>
18#include <linux/qnx4_fs.h> 17#include <linux/qnx4_fs.h>
diff --git a/fs/qnx4/truncate.c b/fs/qnx4/truncate.c
index 86563ec01b39..6437c1c3d1dd 100644
--- a/fs/qnx4/truncate.c
+++ b/fs/qnx4/truncate.c
@@ -10,7 +10,6 @@
10 * 30-06-1998 by Frank DENIS : ugly filler. 10 * 30-06-1998 by Frank DENIS : ugly filler.
11 */ 11 */
12 12
13#include <linux/config.h>
14#include <linux/types.h> 13#include <linux/types.h>
15#include <linux/errno.h> 14#include <linux/errno.h>
16#include <linux/fs.h> 15#include <linux/fs.h>
diff --git a/fs/ramfs/file-mmu.c b/fs/ramfs/file-mmu.c
index 00a933eb820c..86f14cacf641 100644
--- a/fs/ramfs/file-mmu.c
+++ b/fs/ramfs/file-mmu.c
@@ -26,7 +26,7 @@
26 26
27#include <linux/fs.h> 27#include <linux/fs.h>
28 28
29struct address_space_operations ramfs_aops = { 29const struct address_space_operations ramfs_aops = {
30 .readpage = simple_readpage, 30 .readpage = simple_readpage,
31 .prepare_write = simple_prepare_write, 31 .prepare_write = simple_prepare_write,
32 .commit_write = simple_commit_write 32 .commit_write = simple_commit_write
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c
index f443a84b98a5..677139b48e00 100644
--- a/fs/ramfs/file-nommu.c
+++ b/fs/ramfs/file-nommu.c
@@ -27,7 +27,7 @@
27 27
28static int ramfs_nommu_setattr(struct dentry *, struct iattr *); 28static int ramfs_nommu_setattr(struct dentry *, struct iattr *);
29 29
30struct address_space_operations ramfs_aops = { 30const struct address_space_operations ramfs_aops = {
31 .readpage = simple_readpage, 31 .readpage = simple_readpage,
32 .prepare_write = simple_prepare_write, 32 .prepare_write = simple_prepare_write,
33 .commit_write = simple_commit_write 33 .commit_write = simple_commit_write
@@ -283,9 +283,9 @@ unsigned long ramfs_nommu_get_unmapped_area(struct file *file,
283 283
284/*****************************************************************************/ 284/*****************************************************************************/
285/* 285/*
286 * set up a mapping 286 * set up a mapping for shared memory segments
287 */ 287 */
288int ramfs_nommu_mmap(struct file *file, struct vm_area_struct *vma) 288int ramfs_nommu_mmap(struct file *file, struct vm_area_struct *vma)
289{ 289{
290 return 0; 290 return vma->vm_flags & VM_SHARED ? 0 : -ENOSYS;
291} 291}
diff --git a/fs/ramfs/internal.h b/fs/ramfs/internal.h
index 313237631b49..c2bb58e74653 100644
--- a/fs/ramfs/internal.h
+++ b/fs/ramfs/internal.h
@@ -10,6 +10,6 @@
10 */ 10 */
11 11
12 12
13extern struct address_space_operations ramfs_aops; 13extern const struct address_space_operations ramfs_aops;
14extern const struct file_operations ramfs_file_operations; 14extern const struct file_operations ramfs_file_operations;
15extern struct inode_operations ramfs_file_inode_operations; 15extern struct inode_operations ramfs_file_inode_operations;
diff --git a/fs/read_write.c b/fs/read_write.c
index 5bc0e9234f9d..d4cb3183c99c 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -436,7 +436,7 @@ unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to)
436 return seg; 436 return seg;
437} 437}
438 438
439EXPORT_SYMBOL(iov_shorten); 439EXPORT_UNUSED_SYMBOL(iov_shorten); /* June 2006 */
440 440
441/* A write operation does a read from user space and vice versa */ 441/* A write operation does a read from user space and vice versa */
442#define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ) 442#define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ)
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c
index 909f71e9a30f..4a7dbdee1b6d 100644
--- a/fs/reiserfs/bitmap.c
+++ b/fs/reiserfs/bitmap.c
@@ -3,7 +3,6 @@
3 */ 3 */
4/* Reiserfs block (de)allocator, bitmap-based. */ 4/* Reiserfs block (de)allocator, bitmap-based. */
5 5
6#include <linux/config.h>
7#include <linux/time.h> 6#include <linux/time.h>
8#include <linux/reiserfs_fs.h> 7#include <linux/reiserfs_fs.h>
9#include <linux/errno.h> 8#include <linux/errno.h>
diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c
index 973c819f8033..9aabcc0ccd2d 100644
--- a/fs/reiserfs/dir.c
+++ b/fs/reiserfs/dir.c
@@ -2,7 +2,6 @@
2 * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README 2 * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
3 */ 3 */
4 4
5#include <linux/config.h>
6#include <linux/string.h> 5#include <linux/string.h>
7#include <linux/errno.h> 6#include <linux/errno.h>
8#include <linux/fs.h> 7#include <linux/fs.h>
diff --git a/fs/reiserfs/do_balan.c b/fs/reiserfs/do_balan.c
index b2264ba3cc56..fba304e64de8 100644
--- a/fs/reiserfs/do_balan.c
+++ b/fs/reiserfs/do_balan.c
@@ -15,7 +15,6 @@
15 ** 15 **
16 **/ 16 **/
17 17
18#include <linux/config.h>
19#include <asm/uaccess.h> 18#include <asm/uaccess.h>
20#include <linux/time.h> 19#include <linux/time.h>
21#include <linux/reiserfs_fs.h> 20#include <linux/reiserfs_fs.h>
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index 752cea12e30f..f318b58510fd 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -860,8 +860,12 @@ static int reiserfs_submit_file_region_for_write(struct reiserfs_transaction_han
860 // this sets the proper flags for O_SYNC to trigger a commit 860 // this sets the proper flags for O_SYNC to trigger a commit
861 mark_inode_dirty(inode); 861 mark_inode_dirty(inode);
862 reiserfs_write_unlock(inode->i_sb); 862 reiserfs_write_unlock(inode->i_sb);
863 } else 863 } else {
864 reiserfs_write_lock(inode->i_sb);
865 reiserfs_update_inode_transaction(inode);
864 mark_inode_dirty(inode); 866 mark_inode_dirty(inode);
867 reiserfs_write_unlock(inode->i_sb);
868 }
865 869
866 sd_update = 1; 870 sd_update = 1;
867 } 871 }
diff --git a/fs/reiserfs/fix_node.c b/fs/reiserfs/fix_node.c
index 5600d3d60cf7..6d0e554daa9d 100644
--- a/fs/reiserfs/fix_node.c
+++ b/fs/reiserfs/fix_node.c
@@ -34,7 +34,6 @@
34 ** 34 **
35 **/ 35 **/
36 36
37#include <linux/config.h>
38#include <linux/time.h> 37#include <linux/time.h>
39#include <linux/string.h> 38#include <linux/string.h>
40#include <linux/reiserfs_fs.h> 39#include <linux/reiserfs_fs.h>
diff --git a/fs/reiserfs/ibalance.c b/fs/reiserfs/ibalance.c
index 6c5a726fd34b..de391a82b999 100644
--- a/fs/reiserfs/ibalance.c
+++ b/fs/reiserfs/ibalance.c
@@ -2,7 +2,6 @@
2 * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README 2 * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
3 */ 3 */
4 4
5#include <linux/config.h>
6#include <asm/uaccess.h> 5#include <asm/uaccess.h>
7#include <linux/string.h> 6#include <linux/string.h>
8#include <linux/time.h> 7#include <linux/time.h>
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index 9857e50f85e7..12dfdcfbee3d 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -2,7 +2,6 @@
2 * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README 2 * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
3 */ 3 */
4 4
5#include <linux/config.h>
6#include <linux/time.h> 5#include <linux/time.h>
7#include <linux/fs.h> 6#include <linux/fs.h>
8#include <linux/reiserfs_fs.h> 7#include <linux/reiserfs_fs.h>
@@ -2933,6 +2932,11 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
2933 } 2932 }
2934 if (error) 2933 if (error)
2935 goto out; 2934 goto out;
2935 /*
2936 * file size is changed, ctime and mtime are
2937 * to be updated
2938 */
2939 attr->ia_valid |= (ATTR_MTIME | ATTR_CTIME);
2936 } 2940 }
2937 } 2941 }
2938 2942
@@ -2996,7 +3000,7 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
2996 return error; 3000 return error;
2997} 3001}
2998 3002
2999struct address_space_operations reiserfs_address_space_operations = { 3003const struct address_space_operations reiserfs_address_space_operations = {
3000 .writepage = reiserfs_writepage, 3004 .writepage = reiserfs_writepage,
3001 .readpage = reiserfs_readpage, 3005 .readpage = reiserfs_readpage,
3002 .readpages = reiserfs_readpages, 3006 .readpages = reiserfs_readpages,
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index 49d1a53dbef0..9b3672d69367 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -34,7 +34,6 @@
34** from within kupdate, it will ignore the immediate flag 34** from within kupdate, it will ignore the immediate flag
35*/ 35*/
36 36
37#include <linux/config.h>
38#include <asm/uaccess.h> 37#include <asm/uaccess.h>
39#include <asm/system.h> 38#include <asm/system.h>
40 39
diff --git a/fs/reiserfs/lbalance.c b/fs/reiserfs/lbalance.c
index 2533c1f64aba..281f8061ac58 100644
--- a/fs/reiserfs/lbalance.c
+++ b/fs/reiserfs/lbalance.c
@@ -2,7 +2,6 @@
2 * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README 2 * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
3 */ 3 */
4 4
5#include <linux/config.h>
6#include <asm/uaccess.h> 5#include <asm/uaccess.h>
7#include <linux/string.h> 6#include <linux/string.h>
8#include <linux/time.h> 7#include <linux/time.h>
diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c
index 284f7852de8b..c61710e49c62 100644
--- a/fs/reiserfs/namei.c
+++ b/fs/reiserfs/namei.c
@@ -11,7 +11,6 @@
11 * NO WARRANTY 11 * NO WARRANTY
12 */ 12 */
13 13
14#include <linux/config.h>
15#include <linux/time.h> 14#include <linux/time.h>
16#include <linux/bitops.h> 15#include <linux/bitops.h>
17#include <linux/reiserfs_fs.h> 16#include <linux/reiserfs_fs.h>
diff --git a/fs/reiserfs/objectid.c b/fs/reiserfs/objectid.c
index f62590aa9c95..65feba4deb69 100644
--- a/fs/reiserfs/objectid.c
+++ b/fs/reiserfs/objectid.c
@@ -2,7 +2,6 @@
2 * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README 2 * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
3 */ 3 */
4 4
5#include <linux/config.h>
6#include <linux/string.h> 5#include <linux/string.h>
7#include <linux/random.h> 6#include <linux/random.h>
8#include <linux/time.h> 7#include <linux/time.h>
diff --git a/fs/reiserfs/prints.c b/fs/reiserfs/prints.c
index 27bd3a1df2ad..bc808a91eeaa 100644
--- a/fs/reiserfs/prints.c
+++ b/fs/reiserfs/prints.c
@@ -2,7 +2,6 @@
2 * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README 2 * Copyright 2000 by Hans Reiser, licensing governed by reiserfs/README
3 */ 3 */
4 4
5#include <linux/config.h>
6#include <linux/time.h> 5#include <linux/time.h>
7#include <linux/fs.h> 6#include <linux/fs.h>
8#include <linux/reiserfs_fs.h> 7#include <linux/reiserfs_fs.h>
diff --git a/fs/reiserfs/procfs.c b/fs/reiserfs/procfs.c
index 731688e1cfe3..5d8a8cfebc70 100644
--- a/fs/reiserfs/procfs.c
+++ b/fs/reiserfs/procfs.c
@@ -10,7 +10,6 @@
10 10
11/* $Id: procfs.c,v 1.1.8.2 2001/07/15 17:08:42 god Exp $ */ 11/* $Id: procfs.c,v 1.1.8.2 2001/07/15 17:08:42 god Exp $ */
12 12
13#include <linux/config.h>
14#include <linux/module.h> 13#include <linux/module.h>
15#include <linux/time.h> 14#include <linux/time.h>
16#include <linux/seq_file.h> 15#include <linux/seq_file.h>
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c
index d2b25e1ba6e9..8b9b13127136 100644
--- a/fs/reiserfs/stree.c
+++ b/fs/reiserfs/stree.c
@@ -49,7 +49,6 @@
49 * reiserfs_insert_item 49 * reiserfs_insert_item
50 */ 50 */
51 51
52#include <linux/config.h>
53#include <linux/time.h> 52#include <linux/time.h>
54#include <linux/string.h> 53#include <linux/string.h>
55#include <linux/pagemap.h> 54#include <linux/pagemap.h>
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c
index 00f1321e9209..5567328f1041 100644
--- a/fs/reiserfs/super.c
+++ b/fs/reiserfs/super.c
@@ -11,7 +11,6 @@
11 * NO WARRANTY 11 * NO WARRANTY
12 */ 12 */
13 13
14#include <linux/config.h>
15#include <linux/module.h> 14#include <linux/module.h>
16#include <linux/vmalloc.h> 15#include <linux/vmalloc.h>
17#include <linux/time.h> 16#include <linux/time.h>
@@ -2204,7 +2203,7 @@ static ssize_t reiserfs_quota_write(struct super_block *sb, int type,
2204 size_t towrite = len; 2203 size_t towrite = len;
2205 struct buffer_head tmp_bh, *bh; 2204 struct buffer_head tmp_bh, *bh;
2206 2205
2207 mutex_lock(&inode->i_mutex); 2206 mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA);
2208 while (towrite > 0) { 2207 while (towrite > 0) {
2209 tocopy = sb->s_blocksize - offset < towrite ? 2208 tocopy = sb->s_blocksize - offset < towrite ?
2210 sb->s_blocksize - offset : towrite; 2209 sb->s_blocksize - offset : towrite;
diff --git a/fs/reiserfs/tail_conversion.c b/fs/reiserfs/tail_conversion.c
index 196e971c03c9..36f108fc1cf5 100644
--- a/fs/reiserfs/tail_conversion.c
+++ b/fs/reiserfs/tail_conversion.c
@@ -2,7 +2,6 @@
2 * Copyright 1999 Hans Reiser, see reiserfs/README for licensing and copyright details 2 * Copyright 1999 Hans Reiser, see reiserfs/README for licensing and copyright details
3 */ 3 */
4 4
5#include <linux/config.h>
6#include <linux/time.h> 5#include <linux/time.h>
7#include <linux/pagemap.h> 6#include <linux/pagemap.h>
8#include <linux/buffer_head.h> 7#include <linux/buffer_head.h>
diff --git a/fs/romfs/inode.c b/fs/romfs/inode.c
index 283fbc6b8eea..22eed61ebf69 100644
--- a/fs/romfs/inode.c
+++ b/fs/romfs/inode.c
@@ -459,7 +459,7 @@ err_out:
459 459
460/* Mapping from our types to the kernel */ 460/* Mapping from our types to the kernel */
461 461
462static struct address_space_operations romfs_aops = { 462static const struct address_space_operations romfs_aops = {
463 .readpage = romfs_readpage 463 .readpage = romfs_readpage
464}; 464};
465 465
diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c
index ed9a24d19d7d..dae67048baba 100644
--- a/fs/smbfs/file.c
+++ b/fs/smbfs/file.c
@@ -306,7 +306,7 @@ static int smb_commit_write(struct file *file, struct page *page,
306 return status; 306 return status;
307} 307}
308 308
309struct address_space_operations smb_file_aops = { 309const struct address_space_operations smb_file_aops = {
310 .readpage = smb_readpage, 310 .readpage = smb_readpage,
311 .writepage = smb_writepage, 311 .writepage = smb_writepage,
312 .prepare_write = smb_prepare_write, 312 .prepare_write = smb_prepare_write,
diff --git a/fs/smbfs/inode.c b/fs/smbfs/inode.c
index 506ff87c1d4b..a1ed657c3c84 100644
--- a/fs/smbfs/inode.c
+++ b/fs/smbfs/inode.c
@@ -7,7 +7,6 @@
7 * Please add a note about your changes to smbfs in the ChangeLog file. 7 * Please add a note about your changes to smbfs in the ChangeLog file.
8 */ 8 */
9 9
10#include <linux/config.h>
11#include <linux/module.h> 10#include <linux/module.h>
12#include <linux/time.h> 11#include <linux/time.h>
13#include <linux/kernel.h> 12#include <linux/kernel.h>
diff --git a/fs/smbfs/proto.h b/fs/smbfs/proto.h
index 972ed7dad388..34fb462b2379 100644
--- a/fs/smbfs/proto.h
+++ b/fs/smbfs/proto.h
@@ -63,7 +63,7 @@ extern int smb_revalidate_inode(struct dentry *dentry);
63extern int smb_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); 63extern int smb_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat);
64extern int smb_notify_change(struct dentry *dentry, struct iattr *attr); 64extern int smb_notify_change(struct dentry *dentry, struct iattr *attr);
65/* file.c */ 65/* file.c */
66extern struct address_space_operations smb_file_aops; 66extern const struct address_space_operations smb_file_aops;
67extern const struct file_operations smb_file_operations; 67extern const struct file_operations smb_file_operations;
68extern struct inode_operations smb_file_inode_operations; 68extern struct inode_operations smb_file_inode_operations;
69/* ioctl.c */ 69/* ioctl.c */
diff --git a/fs/smbfs/smbiod.c b/fs/smbfs/smbiod.c
index 24577e2c489b..e67540441288 100644
--- a/fs/smbfs/smbiod.c
+++ b/fs/smbfs/smbiod.c
@@ -5,7 +5,6 @@
5 * Copyright (C) 2001, Urban Widmark 5 * Copyright (C) 2001, Urban Widmark
6 */ 6 */
7 7
8#include <linux/config.h>
9 8
10#include <linux/sched.h> 9#include <linux/sched.h>
11#include <linux/kernel.h> 10#include <linux/kernel.h>
diff --git a/fs/splice.c b/fs/splice.c
index 05fd2787be98..684bca3d3a10 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -1307,6 +1307,85 @@ asmlinkage long sys_splice(int fd_in, loff_t __user *off_in,
1307} 1307}
1308 1308
1309/* 1309/*
1310 * Make sure there's data to read. Wait for input if we can, otherwise
1311 * return an appropriate error.
1312 */
1313static int link_ipipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
1314{
1315 int ret;
1316
1317 /*
1318 * Check ->nrbufs without the inode lock first. This function
1319 * is speculative anyways, so missing one is ok.
1320 */
1321 if (pipe->nrbufs)
1322 return 0;
1323
1324 ret = 0;
1325 mutex_lock(&pipe->inode->i_mutex);
1326
1327 while (!pipe->nrbufs) {
1328 if (signal_pending(current)) {
1329 ret = -ERESTARTSYS;
1330 break;
1331 }
1332 if (!pipe->writers)
1333 break;
1334 if (!pipe->waiting_writers) {
1335 if (flags & SPLICE_F_NONBLOCK) {
1336 ret = -EAGAIN;
1337 break;
1338 }
1339 }
1340 pipe_wait(pipe);
1341 }
1342
1343 mutex_unlock(&pipe->inode->i_mutex);
1344 return ret;
1345}
1346
1347/*
1348 * Make sure there's writeable room. Wait for room if we can, otherwise
1349 * return an appropriate error.
1350 */
1351static int link_opipe_prep(struct pipe_inode_info *pipe, unsigned int flags)
1352{
1353 int ret;
1354
1355 /*
1356 * Check ->nrbufs without the inode lock first. This function
1357 * is speculative anyways, so missing one is ok.
1358 */
1359 if (pipe->nrbufs < PIPE_BUFFERS)
1360 return 0;
1361
1362 ret = 0;
1363 mutex_lock(&pipe->inode->i_mutex);
1364
1365 while (pipe->nrbufs >= PIPE_BUFFERS) {
1366 if (!pipe->readers) {
1367 send_sig(SIGPIPE, current, 0);
1368 ret = -EPIPE;
1369 break;
1370 }
1371 if (flags & SPLICE_F_NONBLOCK) {
1372 ret = -EAGAIN;
1373 break;
1374 }
1375 if (signal_pending(current)) {
1376 ret = -ERESTARTSYS;
1377 break;
1378 }
1379 pipe->waiting_writers++;
1380 pipe_wait(pipe);
1381 pipe->waiting_writers--;
1382 }
1383
1384 mutex_unlock(&pipe->inode->i_mutex);
1385 return ret;
1386}
1387
1388/*
1310 * Link contents of ipipe to opipe. 1389 * Link contents of ipipe to opipe.
1311 */ 1390 */
1312static int link_pipe(struct pipe_inode_info *ipipe, 1391static int link_pipe(struct pipe_inode_info *ipipe,
@@ -1314,9 +1393,7 @@ static int link_pipe(struct pipe_inode_info *ipipe,
1314 size_t len, unsigned int flags) 1393 size_t len, unsigned int flags)
1315{ 1394{
1316 struct pipe_buffer *ibuf, *obuf; 1395 struct pipe_buffer *ibuf, *obuf;
1317 int ret, do_wakeup, i, ipipe_first; 1396 int ret = 0, i = 0, nbuf;
1318
1319 ret = do_wakeup = ipipe_first = 0;
1320 1397
1321 /* 1398 /*
1322 * Potential ABBA deadlock, work around it by ordering lock 1399 * Potential ABBA deadlock, work around it by ordering lock
@@ -1324,126 +1401,62 @@ static int link_pipe(struct pipe_inode_info *ipipe,
1324 * could deadlock (one doing tee from A -> B, the other from B -> A). 1401 * could deadlock (one doing tee from A -> B, the other from B -> A).
1325 */ 1402 */
1326 if (ipipe->inode < opipe->inode) { 1403 if (ipipe->inode < opipe->inode) {
1327 ipipe_first = 1; 1404 mutex_lock_nested(&ipipe->inode->i_mutex, I_MUTEX_PARENT);
1328 mutex_lock(&ipipe->inode->i_mutex); 1405 mutex_lock_nested(&opipe->inode->i_mutex, I_MUTEX_CHILD);
1329 mutex_lock(&opipe->inode->i_mutex);
1330 } else { 1406 } else {
1331 mutex_lock(&opipe->inode->i_mutex); 1407 mutex_lock_nested(&opipe->inode->i_mutex, I_MUTEX_PARENT);
1332 mutex_lock(&ipipe->inode->i_mutex); 1408 mutex_lock_nested(&ipipe->inode->i_mutex, I_MUTEX_CHILD);
1333 } 1409 }
1334 1410
1335 for (i = 0;; i++) { 1411 do {
1336 if (!opipe->readers) { 1412 if (!opipe->readers) {
1337 send_sig(SIGPIPE, current, 0); 1413 send_sig(SIGPIPE, current, 0);
1338 if (!ret) 1414 if (!ret)
1339 ret = -EPIPE; 1415 ret = -EPIPE;
1340 break; 1416 break;
1341 } 1417 }
1342 if (ipipe->nrbufs - i) {
1343 ibuf = ipipe->bufs + ((ipipe->curbuf + i) & (PIPE_BUFFERS - 1));
1344 1418
1345 /* 1419 /*
1346 * If we have room, fill this buffer 1420 * If we have iterated all input buffers or ran out of
1347 */ 1421 * output room, break.
1348 if (opipe->nrbufs < PIPE_BUFFERS) { 1422 */
1349 int nbuf = (opipe->curbuf + opipe->nrbufs) & (PIPE_BUFFERS - 1); 1423 if (i >= ipipe->nrbufs || opipe->nrbufs >= PIPE_BUFFERS)
1350 1424 break;
1351 /*
1352 * Get a reference to this pipe buffer,
1353 * so we can copy the contents over.
1354 */
1355 ibuf->ops->get(ipipe, ibuf);
1356
1357 obuf = opipe->bufs + nbuf;
1358 *obuf = *ibuf;
1359
1360 /*
1361 * Don't inherit the gift flag, we need to
1362 * prevent multiple steals of this page.
1363 */
1364 obuf->flags &= ~PIPE_BUF_FLAG_GIFT;
1365
1366 if (obuf->len > len)
1367 obuf->len = len;
1368
1369 opipe->nrbufs++;
1370 do_wakeup = 1;
1371 ret += obuf->len;
1372 len -= obuf->len;
1373
1374 if (!len)
1375 break;
1376 if (opipe->nrbufs < PIPE_BUFFERS)
1377 continue;
1378 }
1379
1380 /*
1381 * We have input available, but no output room.
1382 * If we already copied data, return that. If we
1383 * need to drop the opipe lock, it must be ordered
1384 * last to avoid deadlocks.
1385 */
1386 if ((flags & SPLICE_F_NONBLOCK) || !ipipe_first) {
1387 if (!ret)
1388 ret = -EAGAIN;
1389 break;
1390 }
1391 if (signal_pending(current)) {
1392 if (!ret)
1393 ret = -ERESTARTSYS;
1394 break;
1395 }
1396 if (do_wakeup) {
1397 smp_mb();
1398 if (waitqueue_active(&opipe->wait))
1399 wake_up_interruptible(&opipe->wait);
1400 kill_fasync(&opipe->fasync_readers, SIGIO, POLL_IN);
1401 do_wakeup = 0;
1402 }
1403 1425
1404 opipe->waiting_writers++; 1426 ibuf = ipipe->bufs + ((ipipe->curbuf + i) & (PIPE_BUFFERS - 1));
1405 pipe_wait(opipe); 1427 nbuf = (opipe->curbuf + opipe->nrbufs) & (PIPE_BUFFERS - 1);
1406 opipe->waiting_writers--;
1407 continue;
1408 }
1409 1428
1410 /* 1429 /*
1411 * No input buffers, do the usual checks for available 1430 * Get a reference to this pipe buffer,
1412 * writers and blocking and wait if necessary 1431 * so we can copy the contents over.
1413 */ 1432 */
1414 if (!ipipe->writers) 1433 ibuf->ops->get(ipipe, ibuf);
1415 break; 1434
1416 if (!ipipe->waiting_writers) { 1435 obuf = opipe->bufs + nbuf;
1417 if (ret) 1436 *obuf = *ibuf;
1418 break; 1437
1419 }
1420 /* 1438 /*
1421 * pipe_wait() drops the ipipe mutex. To avoid deadlocks 1439 * Don't inherit the gift flag, we need to
1422 * with another process, we can only safely do that if 1440 * prevent multiple steals of this page.
1423 * the ipipe lock is ordered last.
1424 */ 1441 */
1425 if ((flags & SPLICE_F_NONBLOCK) || ipipe_first) { 1442 obuf->flags &= ~PIPE_BUF_FLAG_GIFT;
1426 if (!ret)
1427 ret = -EAGAIN;
1428 break;
1429 }
1430 if (signal_pending(current)) {
1431 if (!ret)
1432 ret = -ERESTARTSYS;
1433 break;
1434 }
1435 1443
1436 if (waitqueue_active(&ipipe->wait)) 1444 if (obuf->len > len)
1437 wake_up_interruptible_sync(&ipipe->wait); 1445 obuf->len = len;
1438 kill_fasync(&ipipe->fasync_writers, SIGIO, POLL_OUT);
1439 1446
1440 pipe_wait(ipipe); 1447 opipe->nrbufs++;
1441 } 1448 ret += obuf->len;
1449 len -= obuf->len;
1450 i++;
1451 } while (len);
1442 1452
1443 mutex_unlock(&ipipe->inode->i_mutex); 1453 mutex_unlock(&ipipe->inode->i_mutex);
1444 mutex_unlock(&opipe->inode->i_mutex); 1454 mutex_unlock(&opipe->inode->i_mutex);
1445 1455
1446 if (do_wakeup) { 1456 /*
1457 * If we put data in the output pipe, wakeup any potential readers.
1458 */
1459 if (ret > 0) {
1447 smp_mb(); 1460 smp_mb();
1448 if (waitqueue_active(&opipe->wait)) 1461 if (waitqueue_active(&opipe->wait))
1449 wake_up_interruptible(&opipe->wait); 1462 wake_up_interruptible(&opipe->wait);
@@ -1464,14 +1477,29 @@ static long do_tee(struct file *in, struct file *out, size_t len,
1464{ 1477{
1465 struct pipe_inode_info *ipipe = in->f_dentry->d_inode->i_pipe; 1478 struct pipe_inode_info *ipipe = in->f_dentry->d_inode->i_pipe;
1466 struct pipe_inode_info *opipe = out->f_dentry->d_inode->i_pipe; 1479 struct pipe_inode_info *opipe = out->f_dentry->d_inode->i_pipe;
1480 int ret = -EINVAL;
1467 1481
1468 /* 1482 /*
1469 * Link ipipe to the two output pipes, consuming as we go along. 1483 * Duplicate the contents of ipipe to opipe without actually
1484 * copying the data.
1470 */ 1485 */
1471 if (ipipe && opipe) 1486 if (ipipe && opipe && ipipe != opipe) {
1472 return link_pipe(ipipe, opipe, len, flags); 1487 /*
1488 * Keep going, unless we encounter an error. The ipipe/opipe
1489 * ordering doesn't really matter.
1490 */
1491 ret = link_ipipe_prep(ipipe, flags);
1492 if (!ret) {
1493 ret = link_opipe_prep(opipe, flags);
1494 if (!ret) {
1495 ret = link_pipe(ipipe, opipe, len, flags);
1496 if (!ret && (flags & SPLICE_F_NONBLOCK))
1497 ret = -EAGAIN;
1498 }
1499 }
1500 }
1473 1501
1474 return -EINVAL; 1502 return ret;
1475} 1503}
1476 1504
1477asmlinkage long sys_tee(int fdin, int fdout, size_t len, unsigned int flags) 1505asmlinkage long sys_tee(int fdin, int fdout, size_t len, unsigned int flags)
diff --git a/fs/stat.c b/fs/stat.c
index 0f282face322..3a44dcf97da2 100644
--- a/fs/stat.c
+++ b/fs/stat.c
@@ -4,7 +4,6 @@
4 * Copyright (C) 1991, 1992 Linus Torvalds 4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */ 5 */
6 6
7#include <linux/config.h>
8#include <linux/module.h> 7#include <linux/module.h>
9#include <linux/mm.h> 8#include <linux/mm.h>
10#include <linux/errno.h> 9#include <linux/errno.h>
diff --git a/fs/super.c b/fs/super.c
index 8a669f6f3f52..6d4e8174b6db 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -20,7 +20,6 @@
20 * Heavily rewritten for 'one fs - one tree' dcache architecture. AV, Mar 2000 20 * Heavily rewritten for 'one fs - one tree' dcache architecture. AV, Mar 2000
21 */ 21 */
22 22
23#include <linux/config.h>
24#include <linux/module.h> 23#include <linux/module.h>
25#include <linux/slab.h> 24#include <linux/slab.h>
26#include <linux/init.h> 25#include <linux/init.h>
@@ -54,7 +53,7 @@ DEFINE_SPINLOCK(sb_lock);
54 * Allocates and initializes a new &struct super_block. alloc_super() 53 * Allocates and initializes a new &struct super_block. alloc_super()
55 * returns a pointer new superblock or %NULL if allocation had failed. 54 * returns a pointer new superblock or %NULL if allocation had failed.
56 */ 55 */
57static struct super_block *alloc_super(void) 56static struct super_block *alloc_super(struct file_system_type *type)
58{ 57{
59 struct super_block *s = kzalloc(sizeof(struct super_block), GFP_USER); 58 struct super_block *s = kzalloc(sizeof(struct super_block), GFP_USER);
60 static struct super_operations default_op; 59 static struct super_operations default_op;
@@ -73,6 +72,13 @@ static struct super_block *alloc_super(void)
73 INIT_LIST_HEAD(&s->s_inodes); 72 INIT_LIST_HEAD(&s->s_inodes);
74 init_rwsem(&s->s_umount); 73 init_rwsem(&s->s_umount);
75 mutex_init(&s->s_lock); 74 mutex_init(&s->s_lock);
75 lockdep_set_class(&s->s_umount, &type->s_umount_key);
76 /*
77 * The locking rules for s_lock are up to the
78 * filesystem. For example ext3fs has different
79 * lock ordering than usbfs:
80 */
81 lockdep_set_class(&s->s_lock, &type->s_lock_key);
76 down_write(&s->s_umount); 82 down_write(&s->s_umount);
77 s->s_count = S_BIAS; 83 s->s_count = S_BIAS;
78 atomic_set(&s->s_active, 1); 84 atomic_set(&s->s_active, 1);
@@ -296,7 +302,7 @@ retry:
296 } 302 }
297 if (!s) { 303 if (!s) {
298 spin_unlock(&sb_lock); 304 spin_unlock(&sb_lock);
299 s = alloc_super(); 305 s = alloc_super(type);
300 if (!s) 306 if (!s)
301 return ERR_PTR(-ENOMEM); 307 return ERR_PTR(-ENOMEM);
302 goto retry; 308 goto retry;
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index f0b347bd12ca..9889e54e1f13 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -16,7 +16,7 @@
16 16
17extern struct super_block * sysfs_sb; 17extern struct super_block * sysfs_sb;
18 18
19static struct address_space_operations sysfs_aops = { 19static const struct address_space_operations sysfs_aops = {
20 .readpage = simple_readpage, 20 .readpage = simple_readpage,
21 .prepare_write = simple_prepare_write, 21 .prepare_write = simple_prepare_write,
22 .commit_write = simple_commit_write 22 .commit_write = simple_commit_write
@@ -109,6 +109,17 @@ static inline void set_inode_attr(struct inode * inode, struct iattr * iattr)
109 inode->i_ctime = iattr->ia_ctime; 109 inode->i_ctime = iattr->ia_ctime;
110} 110}
111 111
112
113/*
114 * sysfs has a different i_mutex lock order behavior for i_mutex than other
115 * filesystems; sysfs i_mutex is called in many places with subsystem locks
116 * held. At the same time, many of the VFS locking rules do not apply to
117 * sysfs at all (cross directory rename for example). To untangle this mess
118 * (which gives false positives in lockdep), we're giving sysfs inodes their
119 * own class for i_mutex.
120 */
121static struct lock_class_key sysfs_inode_imutex_key;
122
112struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent * sd) 123struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent * sd)
113{ 124{
114 struct inode * inode = new_inode(sysfs_sb); 125 struct inode * inode = new_inode(sysfs_sb);
@@ -118,6 +129,7 @@ struct inode * sysfs_new_inode(mode_t mode, struct sysfs_dirent * sd)
118 inode->i_mapping->a_ops = &sysfs_aops; 129 inode->i_mapping->a_ops = &sysfs_aops;
119 inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info; 130 inode->i_mapping->backing_dev_info = &sysfs_backing_dev_info;
120 inode->i_op = &sysfs_inode_operations; 131 inode->i_op = &sysfs_inode_operations;
132 lockdep_set_class(&inode->i_mutex, &sysfs_inode_imutex_key);
121 133
122 if (sd->s_iattr) { 134 if (sd->s_iattr) {
123 /* sysfs_dirent has non-default attributes 135 /* sysfs_dirent has non-default attributes
diff --git a/fs/sysv/itree.c b/fs/sysv/itree.c
index 86f5f8d43d0f..f2bcccd1d6fc 100644
--- a/fs/sysv/itree.c
+++ b/fs/sysv/itree.c
@@ -465,7 +465,7 @@ static sector_t sysv_bmap(struct address_space *mapping, sector_t block)
465{ 465{
466 return generic_block_bmap(mapping,block,get_block); 466 return generic_block_bmap(mapping,block,get_block);
467} 467}
468struct address_space_operations sysv_aops = { 468const struct address_space_operations sysv_aops = {
469 .readpage = sysv_readpage, 469 .readpage = sysv_readpage,
470 .writepage = sysv_writepage, 470 .writepage = sysv_writepage,
471 .sync_page = block_sync_page, 471 .sync_page = block_sync_page,
diff --git a/fs/sysv/sysv.h b/fs/sysv/sysv.h
index 393a480e4deb..9dcc82120935 100644
--- a/fs/sysv/sysv.h
+++ b/fs/sysv/sysv.h
@@ -161,7 +161,7 @@ extern struct inode_operations sysv_dir_inode_operations;
161extern struct inode_operations sysv_fast_symlink_inode_operations; 161extern struct inode_operations sysv_fast_symlink_inode_operations;
162extern const struct file_operations sysv_file_operations; 162extern const struct file_operations sysv_file_operations;
163extern const struct file_operations sysv_dir_operations; 163extern const struct file_operations sysv_dir_operations;
164extern struct address_space_operations sysv_aops; 164extern const struct address_space_operations sysv_aops;
165extern struct super_operations sysv_sops; 165extern struct super_operations sysv_sops;
166extern struct dentry_operations sysv_dentry_operations; 166extern struct dentry_operations sysv_dentry_operations;
167 167
diff --git a/fs/udf/file.c b/fs/udf/file.c
index e34b00e303f1..a59e5f33daf6 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -95,7 +95,7 @@ static int udf_adinicb_commit_write(struct file *file, struct page *page, unsign
95 return 0; 95 return 0;
96} 96}
97 97
98struct address_space_operations udf_adinicb_aops = { 98const struct address_space_operations udf_adinicb_aops = {
99 .readpage = udf_adinicb_readpage, 99 .readpage = udf_adinicb_readpage,
100 .writepage = udf_adinicb_writepage, 100 .writepage = udf_adinicb_writepage,
101 .sync_page = block_sync_page, 101 .sync_page = block_sync_page,
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 2983afd5e7fd..605f5111b6d8 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -132,7 +132,7 @@ static sector_t udf_bmap(struct address_space *mapping, sector_t block)
132 return generic_block_bmap(mapping,block,udf_get_block); 132 return generic_block_bmap(mapping,block,udf_get_block);
133} 133}
134 134
135struct address_space_operations udf_aops = { 135const struct address_space_operations udf_aops = {
136 .readpage = udf_readpage, 136 .readpage = udf_readpage,
137 .writepage = udf_writepage, 137 .writepage = udf_writepage,
138 .sync_page = block_sync_page, 138 .sync_page = block_sync_page,
diff --git a/fs/udf/super.c b/fs/udf/super.c
index 44fe2cb0bbb2..4df822c881b6 100644
--- a/fs/udf/super.c
+++ b/fs/udf/super.c
@@ -40,7 +40,6 @@
40 40
41#include "udfdecl.h" 41#include "udfdecl.h"
42 42
43#include <linux/config.h>
44#include <linux/blkdev.h> 43#include <linux/blkdev.h>
45#include <linux/slab.h> 44#include <linux/slab.h>
46#include <linux/kernel.h> 45#include <linux/kernel.h>
diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c
index 674bb40edc83..ba068a786563 100644
--- a/fs/udf/symlink.c
+++ b/fs/udf/symlink.c
@@ -113,6 +113,6 @@ out:
113/* 113/*
114 * symlinks can't do much... 114 * symlinks can't do much...
115 */ 115 */
116struct address_space_operations udf_symlink_aops = { 116const struct address_space_operations udf_symlink_aops = {
117 .readpage = udf_symlink_filler, 117 .readpage = udf_symlink_filler,
118}; 118};
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
index 023e19ba5a2e..1033b7cf2939 100644
--- a/fs/udf/udfdecl.h
+++ b/fs/udf/udfdecl.h
@@ -6,7 +6,6 @@
6#include "osta_udf.h" 6#include "osta_udf.h"
7 7
8#include <linux/fs.h> 8#include <linux/fs.h>
9#include <linux/config.h>
10#include <linux/types.h> 9#include <linux/types.h>
11#include <linux/udf_fs_i.h> 10#include <linux/udf_fs_i.h>
12#include <linux/udf_fs_sb.h> 11#include <linux/udf_fs_sb.h>
@@ -47,9 +46,9 @@ extern struct inode_operations udf_dir_inode_operations;
47extern const struct file_operations udf_dir_operations; 46extern const struct file_operations udf_dir_operations;
48extern struct inode_operations udf_file_inode_operations; 47extern struct inode_operations udf_file_inode_operations;
49extern const struct file_operations udf_file_operations; 48extern const struct file_operations udf_file_operations;
50extern struct address_space_operations udf_aops; 49extern const struct address_space_operations udf_aops;
51extern struct address_space_operations udf_adinicb_aops; 50extern const struct address_space_operations udf_adinicb_aops;
52extern struct address_space_operations udf_symlink_aops; 51extern const struct address_space_operations udf_symlink_aops;
53 52
54struct udf_fileident_bh 53struct udf_fileident_bh
55{ 54{
diff --git a/fs/ufs/balloc.c b/fs/ufs/balloc.c
index 95b878e5c7a0..b01804baa120 100644
--- a/fs/ufs/balloc.c
+++ b/fs/ufs/balloc.c
@@ -217,48 +217,6 @@ failed:
217 return; 217 return;
218} 218}
219 219
220static struct page *ufs_get_locked_page(struct address_space *mapping,
221 unsigned long index)
222{
223 struct page *page;
224
225try_again:
226 page = find_lock_page(mapping, index);
227 if (!page) {
228 page = read_cache_page(mapping, index,
229 (filler_t*)mapping->a_ops->readpage,
230 NULL);
231 if (IS_ERR(page)) {
232 printk(KERN_ERR "ufs_change_blocknr: "
233 "read_cache_page error: ino %lu, index: %lu\n",
234 mapping->host->i_ino, index);
235 goto out;
236 }
237
238 lock_page(page);
239
240 if (!PageUptodate(page) || PageError(page)) {
241 unlock_page(page);
242 page_cache_release(page);
243
244 printk(KERN_ERR "ufs_change_blocknr: "
245 "can not read page: ino %lu, index: %lu\n",
246 mapping->host->i_ino, index);
247
248 page = ERR_PTR(-EIO);
249 goto out;
250 }
251 }
252
253 if (unlikely(!page->mapping || !page_has_buffers(page))) {
254 unlock_page(page);
255 page_cache_release(page);
256 goto try_again;/*we really need these buffers*/
257 }
258out:
259 return page;
260}
261
262/* 220/*
263 * Modify inode page cache in such way: 221 * Modify inode page cache in such way:
264 * have - blocks with b_blocknr equal to oldb...oldb+count-1 222 * have - blocks with b_blocknr equal to oldb...oldb+count-1
@@ -311,10 +269,8 @@ static void ufs_change_blocknr(struct inode *inode, unsigned int baseblk,
311 269
312 set_page_dirty(page); 270 set_page_dirty(page);
313 271
314 if (likely(cur_index != index)) { 272 if (likely(cur_index != index))
315 unlock_page(page); 273 ufs_put_locked_page(page);
316 page_cache_release(page);
317 }
318 } 274 }
319 UFSD("EXIT\n"); 275 UFSD("EXIT\n");
320} 276}
diff --git a/fs/ufs/file.c b/fs/ufs/file.c
index 0e5001512a9d..a9c6e5f04fae 100644
--- a/fs/ufs/file.c
+++ b/fs/ufs/file.c
@@ -60,7 +60,3 @@ const struct file_operations ufs_file_operations = {
60 .fsync = ufs_sync_file, 60 .fsync = ufs_sync_file,
61 .sendfile = generic_file_sendfile, 61 .sendfile = generic_file_sendfile,
62}; 62};
63
64struct inode_operations ufs_file_inode_operations = {
65 .truncate = ufs_truncate,
66};
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index 259bd196099d..e7c8615beb65 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -98,7 +98,9 @@ static u64 ufs_frag_map(struct inode *inode, sector_t frag)
98 u64 temp = 0L; 98 u64 temp = 0L;
99 99
100 UFSD(": frag = %llu depth = %d\n", (unsigned long long)frag, depth); 100 UFSD(": frag = %llu depth = %d\n", (unsigned long long)frag, depth);
101 UFSD(": uspi->s_fpbshift = %d ,uspi->s_apbmask = %x, mask=%llx\n",uspi->s_fpbshift,uspi->s_apbmask,mask); 101 UFSD(": uspi->s_fpbshift = %d ,uspi->s_apbmask = %x, mask=%llx\n",
102 uspi->s_fpbshift, uspi->s_apbmask,
103 (unsigned long long)mask);
102 104
103 if (depth == 0) 105 if (depth == 0)
104 return 0; 106 return 0;
@@ -429,7 +431,7 @@ int ufs_getfrag_block(struct inode *inode, sector_t fragment, struct buffer_head
429 431
430 if (!create) { 432 if (!create) {
431 phys64 = ufs_frag_map(inode, fragment); 433 phys64 = ufs_frag_map(inode, fragment);
432 UFSD("phys64 = %llu \n",phys64); 434 UFSD("phys64 = %llu\n", (unsigned long long)phys64);
433 if (phys64) 435 if (phys64)
434 map_bh(bh_result, sb, phys64); 436 map_bh(bh_result, sb, phys64);
435 return 0; 437 return 0;
@@ -574,7 +576,7 @@ static sector_t ufs_bmap(struct address_space *mapping, sector_t block)
574{ 576{
575 return generic_block_bmap(mapping,block,ufs_getfrag_block); 577 return generic_block_bmap(mapping,block,ufs_getfrag_block);
576} 578}
577struct address_space_operations ufs_aops = { 579const struct address_space_operations ufs_aops = {
578 .readpage = ufs_readpage, 580 .readpage = ufs_readpage,
579 .writepage = ufs_writepage, 581 .writepage = ufs_writepage,
580 .sync_page = block_sync_page, 582 .sync_page = block_sync_page,
@@ -841,14 +843,17 @@ int ufs_sync_inode (struct inode *inode)
841 843
842void ufs_delete_inode (struct inode * inode) 844void ufs_delete_inode (struct inode * inode)
843{ 845{
846 loff_t old_i_size;
847
844 truncate_inode_pages(&inode->i_data, 0); 848 truncate_inode_pages(&inode->i_data, 0);
845 /*UFS_I(inode)->i_dtime = CURRENT_TIME;*/ 849 /*UFS_I(inode)->i_dtime = CURRENT_TIME;*/
846 lock_kernel(); 850 lock_kernel();
847 mark_inode_dirty(inode); 851 mark_inode_dirty(inode);
848 ufs_update_inode(inode, IS_SYNC(inode)); 852 ufs_update_inode(inode, IS_SYNC(inode));
853 old_i_size = inode->i_size;
849 inode->i_size = 0; 854 inode->i_size = 0;
850 if (inode->i_blocks) 855 if (inode->i_blocks && ufs_truncate(inode, old_i_size))
851 ufs_truncate (inode); 856 ufs_warning(inode->i_sb, __FUNCTION__, "ufs_truncate failed\n");
852 ufs_free_inode (inode); 857 ufs_free_inode (inode);
853 unlock_kernel(); 858 unlock_kernel();
854} 859}
diff --git a/fs/ufs/super.c b/fs/ufs/super.c
index 74ef5e9bedff..992ee0b87cc3 100644
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -64,7 +64,6 @@
64 */ 64 */
65 65
66 66
67#include <linux/config.h>
68#include <linux/module.h> 67#include <linux/module.h>
69#include <linux/bitops.h> 68#include <linux/bitops.h>
70 69
@@ -1327,7 +1326,7 @@ static ssize_t ufs_quota_write(struct super_block *sb, int type,
1327 size_t towrite = len; 1326 size_t towrite = len;
1328 struct buffer_head *bh; 1327 struct buffer_head *bh;
1329 1328
1330 mutex_lock(&inode->i_mutex); 1329 mutex_lock_nested(&inode->i_mutex, I_MUTEX_QUOTA);
1331 while (towrite > 0) { 1330 while (towrite > 0) {
1332 tocopy = sb->s_blocksize - offset < towrite ? 1331 tocopy = sb->s_blocksize - offset < towrite ?
1333 sb->s_blocksize - offset : towrite; 1332 sb->s_blocksize - offset : towrite;
diff --git a/fs/ufs/truncate.c b/fs/ufs/truncate.c
index 3c3b301f8701..c9b55872079b 100644
--- a/fs/ufs/truncate.c
+++ b/fs/ufs/truncate.c
@@ -369,24 +369,97 @@ static int ufs_trunc_tindirect (struct inode * inode)
369 UFSD("EXIT\n"); 369 UFSD("EXIT\n");
370 return retry; 370 return retry;
371} 371}
372 372
373void ufs_truncate (struct inode * inode) 373static int ufs_alloc_lastblock(struct inode *inode)
374{ 374{
375 int err = 0;
376 struct address_space *mapping = inode->i_mapping;
377 struct ufs_sb_private_info *uspi = UFS_SB(inode->i_sb)->s_uspi;
375 struct ufs_inode_info *ufsi = UFS_I(inode); 378 struct ufs_inode_info *ufsi = UFS_I(inode);
376 struct super_block * sb; 379 unsigned lastfrag, i, end;
377 struct ufs_sb_private_info * uspi; 380 struct page *lastpage;
378 int retry; 381 struct buffer_head *bh;
382
383 lastfrag = (i_size_read(inode) + uspi->s_fsize - 1) >> uspi->s_fshift;
384
385 if (!lastfrag) {
386 ufsi->i_lastfrag = 0;
387 goto out;
388 }
389 lastfrag--;
390
391 lastpage = ufs_get_locked_page(mapping, lastfrag >>
392 (PAGE_CACHE_SHIFT - inode->i_blkbits));
393 if (IS_ERR(lastpage)) {
394 err = -EIO;
395 goto out;
396 }
397
398 end = lastfrag & ((1 << (PAGE_CACHE_SHIFT - inode->i_blkbits)) - 1);
399 bh = page_buffers(lastpage);
400 for (i = 0; i < end; ++i)
401 bh = bh->b_this_page;
402
403 if (!buffer_mapped(bh)) {
404 err = ufs_getfrag_block(inode, lastfrag, bh, 1);
405
406 if (unlikely(err))
407 goto out_unlock;
408
409 if (buffer_new(bh)) {
410 clear_buffer_new(bh);
411 unmap_underlying_metadata(bh->b_bdev,
412 bh->b_blocknr);
413 /*
414 * we do not zeroize fragment, because of
415 * if it maped to hole, it already contains zeroes
416 */
417 set_buffer_uptodate(bh);
418 mark_buffer_dirty(bh);
419 set_page_dirty(lastpage);
420 }
421 }
422out_unlock:
423 ufs_put_locked_page(lastpage);
424out:
425 return err;
426}
427
428int ufs_truncate(struct inode *inode, loff_t old_i_size)
429{
430 struct ufs_inode_info *ufsi = UFS_I(inode);
431 struct super_block *sb = inode->i_sb;
432 struct ufs_sb_private_info *uspi = UFS_SB(sb)->s_uspi;
433 int retry, err = 0;
379 434
380 UFSD("ENTER\n"); 435 UFSD("ENTER\n");
381 sb = inode->i_sb;
382 uspi = UFS_SB(sb)->s_uspi;
383 436
384 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))) 437 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
385 return; 438 S_ISLNK(inode->i_mode)))
439 return -EINVAL;
386 if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) 440 if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
387 return; 441 return -EPERM;
442
443 if (inode->i_size > old_i_size) {
444 /*
445 * if we expand file we should care about
446 * allocation of block for last byte first of all
447 */
448 err = ufs_alloc_lastblock(inode);
449
450 if (err) {
451 i_size_write(inode, old_i_size);
452 goto out;
453 }
454 /*
455 * go away, because of we expand file, and we do not
456 * need free blocks, and zeroizes page
457 */
458 lock_kernel();
459 goto almost_end;
460 }
388 461
389 block_truncate_page(inode->i_mapping, inode->i_size, ufs_getfrag_block); 462 block_truncate_page(inode->i_mapping, inode->i_size, ufs_getfrag_block);
390 463
391 lock_kernel(); 464 lock_kernel();
392 while (1) { 465 while (1) {
@@ -404,9 +477,58 @@ void ufs_truncate (struct inode * inode)
404 yield(); 477 yield();
405 } 478 }
406 479
480 if (inode->i_size < old_i_size) {
481 /*
482 * now we should have enough space
483 * to allocate block for last byte
484 */
485 err = ufs_alloc_lastblock(inode);
486 if (err)
487 /*
488 * looks like all the same - we have no space,
489 * but we truncate file already
490 */
491 inode->i_size = (ufsi->i_lastfrag - 1) * uspi->s_fsize;
492 }
493almost_end:
407 inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; 494 inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
408 ufsi->i_lastfrag = DIRECT_FRAGMENT;
409 unlock_kernel(); 495 unlock_kernel();
410 mark_inode_dirty(inode); 496 mark_inode_dirty(inode);
411 UFSD("EXIT\n"); 497out:
498 UFSD("EXIT: err %d\n", err);
499 return err;
412} 500}
501
502
503/*
504 * We don't define our `inode->i_op->truncate', and call it here,
505 * because of:
506 * - there is no way to know old size
507 * - there is no way inform user about error, if it happens in `truncate'
508 */
509static int ufs_setattr(struct dentry *dentry, struct iattr *attr)
510{
511 struct inode *inode = dentry->d_inode;
512 unsigned int ia_valid = attr->ia_valid;
513 int error;
514
515 error = inode_change_ok(inode, attr);
516 if (error)
517 return error;
518
519 if (ia_valid & ATTR_SIZE &&
520 attr->ia_size != i_size_read(inode)) {
521 loff_t old_i_size = inode->i_size;
522 error = vmtruncate(inode, attr->ia_size);
523 if (error)
524 return error;
525 error = ufs_truncate(inode, old_i_size);
526 if (error)
527 return error;
528 }
529 return inode_setattr(inode, attr);
530}
531
532struct inode_operations ufs_file_inode_operations = {
533 .setattr = ufs_setattr,
534};
diff --git a/fs/ufs/util.c b/fs/ufs/util.c
index a2f13f45708b..337cf2c46d10 100644
--- a/fs/ufs/util.c
+++ b/fs/ufs/util.c
@@ -233,3 +233,57 @@ ufs_set_inode_dev(struct super_block *sb, struct ufs_inode_info *ufsi, dev_t dev
233 else 233 else
234 ufsi->i_u1.i_data[0] = fs32; 234 ufsi->i_u1.i_data[0] = fs32;
235} 235}
236
237/**
238 * ufs_get_locked_page() - locate, pin and lock a pagecache page, if not exist
239 * read it from disk.
240 * @mapping: the address_space to search
241 * @index: the page index
242 *
243 * Locates the desired pagecache page, if not exist we'll read it,
244 * locks it, increments its reference
245 * count and returns its address.
246 *
247 */
248
249struct page *ufs_get_locked_page(struct address_space *mapping,
250 pgoff_t index)
251{
252 struct page *page;
253
254try_again:
255 page = find_lock_page(mapping, index);
256 if (!page) {
257 page = read_cache_page(mapping, index,
258 (filler_t*)mapping->a_ops->readpage,
259 NULL);
260 if (IS_ERR(page)) {
261 printk(KERN_ERR "ufs_change_blocknr: "
262 "read_cache_page error: ino %lu, index: %lu\n",
263 mapping->host->i_ino, index);
264 goto out;
265 }
266
267 lock_page(page);
268
269 if (!PageUptodate(page) || PageError(page)) {
270 unlock_page(page);
271 page_cache_release(page);
272
273 printk(KERN_ERR "ufs_change_blocknr: "
274 "can not read page: ino %lu, index: %lu\n",
275 mapping->host->i_ino, index);
276
277 page = ERR_PTR(-EIO);
278 goto out;
279 }
280 }
281
282 if (unlikely(!page->mapping || !page_has_buffers(page))) {
283 unlock_page(page);
284 page_cache_release(page);
285 goto try_again;/*we really need these buffers*/
286 }
287out:
288 return page;
289}
diff --git a/fs/ufs/util.h b/fs/ufs/util.h
index 406981fff5e7..28fce6c239b5 100644
--- a/fs/ufs/util.h
+++ b/fs/ufs/util.h
@@ -251,6 +251,14 @@ extern void _ubh_ubhcpymem_(struct ufs_sb_private_info *, unsigned char *, struc
251#define ubh_memcpyubh(ubh,mem,size) _ubh_memcpyubh_(uspi,ubh,mem,size) 251#define ubh_memcpyubh(ubh,mem,size) _ubh_memcpyubh_(uspi,ubh,mem,size)
252extern void _ubh_memcpyubh_(struct ufs_sb_private_info *, struct ufs_buffer_head *, unsigned char *, unsigned); 252extern void _ubh_memcpyubh_(struct ufs_sb_private_info *, struct ufs_buffer_head *, unsigned char *, unsigned);
253 253
254/* This functions works with cache pages*/
255extern struct page *ufs_get_locked_page(struct address_space *mapping,
256 pgoff_t index);
257static inline void ufs_put_locked_page(struct page *page)
258{
259 unlock_page(page);
260 page_cache_release(page);
261}
254 262
255 263
256/* 264/*
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 3e807b828e22..c40f81ba9b13 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -1454,7 +1454,7 @@ xfs_vm_invalidatepage(
1454 block_invalidatepage(page, offset); 1454 block_invalidatepage(page, offset);
1455} 1455}
1456 1456
1457struct address_space_operations xfs_address_space_operations = { 1457const struct address_space_operations xfs_address_space_operations = {
1458 .readpage = xfs_vm_readpage, 1458 .readpage = xfs_vm_readpage,
1459 .readpages = xfs_vm_readpages, 1459 .readpages = xfs_vm_readpages,
1460 .writepage = xfs_vm_writepage, 1460 .writepage = xfs_vm_writepage,
diff --git a/fs/xfs/linux-2.6/xfs_aops.h b/fs/xfs/linux-2.6/xfs_aops.h
index 706d8c781b8a..2244e516b66a 100644
--- a/fs/xfs/linux-2.6/xfs_aops.h
+++ b/fs/xfs/linux-2.6/xfs_aops.h
@@ -40,7 +40,7 @@ typedef struct xfs_ioend {
40 struct work_struct io_work; /* xfsdatad work queue */ 40 struct work_struct io_work; /* xfsdatad work queue */
41} xfs_ioend_t; 41} xfs_ioend_t;
42 42
43extern struct address_space_operations xfs_address_space_operations; 43extern const struct address_space_operations xfs_address_space_operations;
44extern int xfs_get_blocks(struct inode *, sector_t, struct buffer_head *, int); 44extern int xfs_get_blocks(struct inode *, sector_t, struct buffer_head *, int);
45 45
46#endif /* __XFS_AOPS_H__ */ 46#endif /* __XFS_AOPS_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c
index 26fed0756f01..2af528dcfb04 100644
--- a/fs/xfs/linux-2.6/xfs_buf.c
+++ b/fs/xfs/linux-2.6/xfs_buf.c
@@ -1520,7 +1520,7 @@ xfs_mapping_buftarg(
1520 struct backing_dev_info *bdi; 1520 struct backing_dev_info *bdi;
1521 struct inode *inode; 1521 struct inode *inode;
1522 struct address_space *mapping; 1522 struct address_space *mapping;
1523 static struct address_space_operations mapping_aops = { 1523 static const struct address_space_operations mapping_aops = {
1524 .sync_page = block_sync_page, 1524 .sync_page = block_sync_page,
1525 .migratepage = fail_migrate_page, 1525 .migratepage = fail_migrate_page,
1526 }; 1526 };
diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h
index 4dd6592d5a4c..ceda3a2859d2 100644
--- a/fs/xfs/linux-2.6/xfs_buf.h
+++ b/fs/xfs/linux-2.6/xfs_buf.h
@@ -18,7 +18,6 @@
18#ifndef __XFS_BUF_H__ 18#ifndef __XFS_BUF_H__
19#define __XFS_BUF_H__ 19#define __XFS_BUF_H__
20 20
21#include <linux/config.h>
22#include <linux/list.h> 21#include <linux/list.h>
23#include <linux/types.h> 22#include <linux/types.h>
24#include <linux/spinlock.h> 23#include <linux/spinlock.h>
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c
index 601f01c92f7f..270db0f3861d 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl32.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl32.c
@@ -15,7 +15,6 @@
15 * along with this program; if not, write the Free Software Foundation, 15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */ 17 */
18#include <linux/config.h>
19#include <linux/compat.h> 18#include <linux/compat.h>
20#include <linux/init.h> 19#include <linux/init.h>
21#include <linux/ioctl.h> 20#include <linux/ioctl.h>
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c
index 12810baeb5d4..d9180020de63 100644
--- a/fs/xfs/linux-2.6/xfs_iops.c
+++ b/fs/xfs/linux-2.6/xfs_iops.c
@@ -419,16 +419,15 @@ xfs_vn_link(
419 int error; 419 int error;
420 420
421 ip = old_dentry->d_inode; /* inode being linked to */ 421 ip = old_dentry->d_inode; /* inode being linked to */
422 if (S_ISDIR(ip->i_mode))
423 return -EPERM;
424
425 tdvp = vn_from_inode(dir); 422 tdvp = vn_from_inode(dir);
426 vp = vn_from_inode(ip); 423 vp = vn_from_inode(ip);
427 424
425 VN_HOLD(vp);
428 error = bhv_vop_link(tdvp, vp, dentry, NULL); 426 error = bhv_vop_link(tdvp, vp, dentry, NULL);
429 if (likely(!error)) { 427 if (unlikely(error)) {
428 VN_RELE(vp);
429 } else {
430 VMODIFY(tdvp); 430 VMODIFY(tdvp);
431 VN_HOLD(vp);
432 xfs_validate_fields(ip, &vattr); 431 xfs_validate_fields(ip, &vattr);
433 d_instantiate(dentry, ip); 432 d_instantiate(dentry, ip);
434 } 433 }
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
index aa26ab906c88..a13f75c1a936 100644
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/linux-2.6/xfs_linux.h
@@ -19,7 +19,6 @@
19#define __XFS_LINUX__ 19#define __XFS_LINUX__
20 20
21#include <linux/types.h> 21#include <linux/types.h>
22#include <linux/config.h>
23 22
24/* 23/*
25 * Some types are conditional depending on the target system. 24 * Some types are conditional depending on the target system.
@@ -140,9 +139,7 @@ BUFFER_FNS(PrivateStart, unwritten);
140#define current_pid() (current->pid) 139#define current_pid() (current->pid)
141#define current_fsuid(cred) (current->fsuid) 140#define current_fsuid(cred) (current->fsuid)
142#define current_fsgid(cred) (current->fsgid) 141#define current_fsgid(cred) (current->fsgid)
143#define current_set_flags(f) (current->flags |= (f))
144#define current_test_flags(f) (current->flags & (f)) 142#define current_test_flags(f) (current->flags & (f))
145#define current_clear_flags(f) (current->flags & ~(f))
146#define current_set_flags_nested(sp, f) \ 143#define current_set_flags_nested(sp, f) \
147 (*(sp) = current->flags, current->flags |= (f)) 144 (*(sp) = current->flags, current->flags |= (f))
148#define current_clear_flags_nested(sp, f) \ 145#define current_clear_flags_nested(sp, f) \
@@ -218,7 +215,6 @@ BUFFER_FNS(PrivateStart, unwritten);
218#define MIN(a,b) (min(a,b)) 215#define MIN(a,b) (min(a,b))
219#define MAX(a,b) (max(a,b)) 216#define MAX(a,b) (max(a,b))
220#define howmany(x, y) (((x)+((y)-1))/(y)) 217#define howmany(x, y) (((x)+((y)-1))/(y))
221#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
222 218
223/* 219/*
224 * Various platform dependent calls that don't fit anywhere else 220 * Various platform dependent calls that don't fit anywhere else
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index 35c6a01963a7..c42b3221b20c 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -93,7 +93,7 @@ typedef enum {
93 */ 93 */
94static inline struct bhv_vnode *vn_from_inode(struct inode *inode) 94static inline struct bhv_vnode *vn_from_inode(struct inode *inode)
95{ 95{
96 return (bhv_vnode_t *)list_entry(inode, bhv_vnode_t, v_inode); 96 return container_of(inode, bhv_vnode_t, v_inode);
97} 97}
98static inline struct inode *vn_to_inode(struct bhv_vnode *vnode) 98static inline struct inode *vn_to_inode(struct bhv_vnode *vnode)
99{ 99{
diff --git a/fs/xfs/xfs_behavior.h b/fs/xfs/xfs_behavior.h
index 1d8ff103201c..6e6e56fb352d 100644
--- a/fs/xfs/xfs_behavior.h
+++ b/fs/xfs/xfs_behavior.h
@@ -78,15 +78,12 @@
78 * 78 *
79 */ 79 */
80 80
81struct bhv_head_lock;
82
83/* 81/*
84 * Behavior head. Head of the chain of behaviors. 82 * Behavior head. Head of the chain of behaviors.
85 * Contained within each virtualized object data structure. 83 * Contained within each virtualized object data structure.
86 */ 84 */
87typedef struct bhv_head { 85typedef struct bhv_head {
88 struct bhv_desc *bh_first; /* first behavior in chain */ 86 struct bhv_desc *bh_first; /* first behavior in chain */
89 struct bhv_head_lock *bh_lockp; /* pointer to lock info struct */
90} bhv_head_t; 87} bhv_head_t;
91 88
92/* 89/*
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 5fa0adb7e173..86c1bf0bba9e 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1961,9 +1961,9 @@ xfs_iunlink_remove(
1961 xfs_agino_t agino; 1961 xfs_agino_t agino;
1962 xfs_agino_t next_agino; 1962 xfs_agino_t next_agino;
1963 xfs_buf_t *last_ibp; 1963 xfs_buf_t *last_ibp;
1964 xfs_dinode_t *last_dip; 1964 xfs_dinode_t *last_dip = NULL;
1965 short bucket_index; 1965 short bucket_index;
1966 int offset, last_offset; 1966 int offset, last_offset = 0;
1967 int error; 1967 int error;
1968 int agi_ok; 1968 int agi_ok;
1969 1969
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index d8f5d4cbe8b7..e730328636c3 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -1740,10 +1740,10 @@ xlog_write(xfs_mount_t * mp,
1740 xlog_in_core_t **commit_iclog, 1740 xlog_in_core_t **commit_iclog,
1741 uint flags) 1741 uint flags)
1742{ 1742{
1743 xlog_t *log = mp->m_log; 1743 xlog_t *log = mp->m_log;
1744 xlog_ticket_t *ticket = (xlog_ticket_t *)tic; 1744 xlog_ticket_t *ticket = (xlog_ticket_t *)tic;
1745 xlog_in_core_t *iclog = NULL; /* ptr to current in-core log */
1745 xlog_op_header_t *logop_head; /* ptr to log operation header */ 1746 xlog_op_header_t *logop_head; /* ptr to log operation header */
1746 xlog_in_core_t *iclog; /* ptr to current in-core log */
1747 __psint_t ptr; /* copy address into data region */ 1747 __psint_t ptr; /* copy address into data region */
1748 int len; /* # xlog_write() bytes 2 still copy */ 1748 int len; /* # xlog_write() bytes 2 still copy */
1749 int index; /* region index currently copying */ 1749 int index; /* region index currently copying */
diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c
index 55b4237c2153..3cb678e3a132 100644
--- a/fs/xfs/xfs_log_recover.c
+++ b/fs/xfs/xfs_log_recover.c
@@ -990,6 +990,8 @@ xlog_find_zeroed(
990 xfs_daddr_t num_scan_bblks; 990 xfs_daddr_t num_scan_bblks;
991 int error, log_bbnum = log->l_logBBsize; 991 int error, log_bbnum = log->l_logBBsize;
992 992
993 *blk_no = 0;
994
993 /* check totally zeroed log */ 995 /* check totally zeroed log */
994 bp = xlog_get_bp(log, 1); 996 bp = xlog_get_bp(log, 1);
995 if (!bp) 997 if (!bp)
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index ed7579beb6b0..4be5c0b2d296 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -2028,7 +2028,7 @@ xfs_icsb_balance_counter(
2028 xfs_sb_field_t field, 2028 xfs_sb_field_t field,
2029 int flags) 2029 int flags)
2030{ 2030{
2031 uint64_t count, resid = 0; 2031 uint64_t count, resid;
2032 int weight = num_online_cpus(); 2032 int weight = num_online_cpus();
2033 int s; 2033 int s;
2034 2034
@@ -2060,6 +2060,7 @@ xfs_icsb_balance_counter(
2060 break; 2060 break;
2061 default: 2061 default:
2062 BUG(); 2062 BUG();
2063 count = resid = 0; /* quiet, gcc */
2063 break; 2064 break;
2064 } 2065 }
2065 2066
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index 0c1e42b037ef..5a0b678956e0 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -1929,7 +1929,7 @@ xfs_growfs_rt(
1929 /* 1929 /*
1930 * Initial error checking. 1930 * Initial error checking.
1931 */ 1931 */
1932 if (mp->m_rtdev_targp || mp->m_rbmip == NULL || 1932 if (mp->m_rtdev_targp == NULL || mp->m_rbmip == NULL ||
1933 (nrblocks = in->newblocks) <= sbp->sb_rblocks || 1933 (nrblocks = in->newblocks) <= sbp->sb_rblocks ||
1934 (sbp->sb_rblocks && (in->extsize != sbp->sb_rextsize))) 1934 (sbp->sb_rblocks && (in->extsize != sbp->sb_rextsize)))
1935 return XFS_ERROR(EINVAL); 1935 return XFS_ERROR(EINVAL);
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
index cb65c3a603f5..9dc88b380608 100644
--- a/fs/xfs/xfs_trans.h
+++ b/fs/xfs/xfs_trans.h
@@ -338,8 +338,6 @@ typedef void (*xfs_trans_callback_t)(struct xfs_trans *, void *);
338typedef struct xfs_trans { 338typedef struct xfs_trans {
339 unsigned int t_magic; /* magic number */ 339 unsigned int t_magic; /* magic number */
340 xfs_log_callback_t t_logcb; /* log callback struct */ 340 xfs_log_callback_t t_logcb; /* log callback struct */
341 struct xfs_trans *t_forw; /* async list pointers */
342 struct xfs_trans *t_back; /* async list pointers */
343 unsigned int t_type; /* transaction type */ 341 unsigned int t_type; /* transaction type */
344 unsigned int t_log_res; /* amt of log space resvd */ 342 unsigned int t_log_res; /* amt of log space resvd */
345 unsigned int t_log_count; /* count for perm log res */ 343 unsigned int t_log_count; /* count for perm log res */
@@ -364,9 +362,11 @@ typedef struct xfs_trans {
364 long t_res_fdblocks_delta; /* on-disk only chg */ 362 long t_res_fdblocks_delta; /* on-disk only chg */
365 long t_frextents_delta;/* superblock freextents chg*/ 363 long t_frextents_delta;/* superblock freextents chg*/
366 long t_res_frextents_delta; /* on-disk only chg */ 364 long t_res_frextents_delta; /* on-disk only chg */
365#ifdef DEBUG
367 long t_ag_freeblks_delta; /* debugging counter */ 366 long t_ag_freeblks_delta; /* debugging counter */
368 long t_ag_flist_delta; /* debugging counter */ 367 long t_ag_flist_delta; /* debugging counter */
369 long t_ag_btree_delta; /* debugging counter */ 368 long t_ag_btree_delta; /* debugging counter */
369#endif
370 long t_dblocks_delta;/* superblock dblocks change */ 370 long t_dblocks_delta;/* superblock dblocks change */
371 long t_agcount_delta;/* superblock agcount change */ 371 long t_agcount_delta;/* superblock agcount change */
372 long t_imaxpct_delta;/* superblock imaxpct change */ 372 long t_imaxpct_delta;/* superblock imaxpct change */
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index 00a6b7dc24a0..23cfa5837728 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -2603,8 +2603,7 @@ xfs_link(
2603 vn_trace_entry(src_vp, __FUNCTION__, (inst_t *)__return_address); 2603 vn_trace_entry(src_vp, __FUNCTION__, (inst_t *)__return_address);
2604 2604
2605 target_namelen = VNAMELEN(dentry); 2605 target_namelen = VNAMELEN(dentry);
2606 if (VN_ISDIR(src_vp)) 2606 ASSERT(!VN_ISDIR(src_vp));
2607 return XFS_ERROR(EPERM);
2608 2607
2609 sip = xfs_vtoi(src_vp); 2608 sip = xfs_vtoi(src_vp);
2610 tdp = XFS_BHVTOI(target_dir_bdp); 2609 tdp = XFS_BHVTOI(target_dir_bdp);
@@ -2699,9 +2698,8 @@ xfs_link(
2699 xfs_trans_log_inode(tp, tdp, XFS_ILOG_CORE); 2698 xfs_trans_log_inode(tp, tdp, XFS_ILOG_CORE);
2700 2699
2701 error = xfs_bumplink(tp, sip); 2700 error = xfs_bumplink(tp, sip);
2702 if (error) { 2701 if (error)
2703 goto abort_return; 2702 goto abort_return;
2704 }
2705 2703
2706 /* 2704 /*
2707 * If this is a synchronous mount, make sure that the 2705 * If this is a synchronous mount, make sure that the
@@ -2719,9 +2717,8 @@ xfs_link(
2719 } 2717 }
2720 2718
2721 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL); 2719 error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES, NULL);
2722 if (error) { 2720 if (error)
2723 goto std_return; 2721 goto std_return;
2724 }
2725 2722
2726 /* Fall through to std_return with error = 0. */ 2723 /* Fall through to std_return with error = 0. */
2727std_return: 2724std_return:
@@ -2742,6 +2739,8 @@ std_return:
2742 xfs_trans_cancel(tp, cancel_flags); 2739 xfs_trans_cancel(tp, cancel_flags);
2743 goto std_return; 2740 goto std_return;
2744} 2741}
2742
2743
2745/* 2744/*
2746 * xfs_mkdir 2745 * xfs_mkdir
2747 * 2746 *