aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/Makefile2
-rw-r--r--fs/char_dev.c87
-rw-r--r--fs/cifs/CHANGES18
-rw-r--r--fs/cifs/Makefile2
-rw-r--r--fs/cifs/README7
-rw-r--r--fs/cifs/cifsencrypt.c42
-rw-r--r--fs/cifs/cifsfs.c5
-rw-r--r--fs/cifs/cifsfs.h2
-rw-r--r--fs/cifs/cifsglob.h11
-rw-r--r--fs/cifs/cifspdu.h13
-rw-r--r--fs/cifs/cifsproto.h15
-rw-r--r--fs/cifs/cifssmb.c135
-rw-r--r--fs/cifs/connect.c99
-rw-r--r--fs/cifs/dir.c7
-rw-r--r--fs/cifs/file.c94
-rw-r--r--fs/cifs/inode.c22
-rw-r--r--fs/cifs/link.c2
-rw-r--r--fs/cifs/misc.c46
-rw-r--r--fs/cifs/ntlmssp.c129
-rw-r--r--fs/cifs/ntlmssp.h2
-rw-r--r--fs/cifs/readdir.c7
-rw-r--r--fs/cifs/transport.c22
-rw-r--r--fs/dcache.c50
-rw-r--r--fs/direct-io.c3
-rw-r--r--fs/dquot.c6
-rw-r--r--fs/exec.c2
-rw-r--r--fs/fcntl.c3
-rw-r--r--fs/freevxfs/vxfs_olt.c9
-rw-r--r--fs/hfsplus/bnode.c6
-rw-r--r--fs/hfsplus/btree.c3
-rw-r--r--fs/hppfs/hppfs_kern.c14
-rw-r--r--fs/inode.c15
-rw-r--r--fs/jffs2/background.c3
-rw-r--r--fs/locks.c45
-rw-r--r--fs/msdos/namei.c15
-rw-r--r--fs/namei.c3
-rw-r--r--fs/pipe.c4
-rw-r--r--fs/proc/base.c13
-rw-r--r--fs/proc/proc_misc.c163
-rw-r--r--fs/select.c8
-rw-r--r--fs/smbfs/file.c6
-rw-r--r--fs/splice.c202
-rw-r--r--fs/sync.c164
-rw-r--r--fs/sysfs/dir.c2
-rw-r--r--fs/sysfs/file.c2
-rw-r--r--fs/sysfs/inode.c3
-rw-r--r--fs/sysv/dir.c6
-rw-r--r--fs/udf/inode.c6
-rw-r--r--fs/vfat/namei.c18
-rw-r--r--fs/xfs/linux-2.6/xfs_file.c113
-rw-r--r--fs/xfs/linux-2.6/xfs_linux.h1
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c120
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.h11
-rw-r--r--fs/xfs/linux-2.6/xfs_super.c11
-rw-r--r--fs/xfs/linux-2.6/xfs_vnode.h12
-rw-r--r--fs/xfs/quota/xfs_qm.c17
-rw-r--r--fs/xfs/quota/xfs_trans_dquot.c68
-rw-r--r--fs/xfs/xfs_bmap.c11
-rw-r--r--fs/xfs/xfs_bmap.h9
-rw-r--r--fs/xfs/xfs_clnt.h1
-rw-r--r--fs/xfs/xfs_error.h3
-rw-r--r--fs/xfs/xfs_mount.c71
-rw-r--r--fs/xfs/xfs_mount.h5
-rw-r--r--fs/xfs/xfs_quota.h5
-rw-r--r--fs/xfs/xfs_vfsops.c10
-rw-r--r--fs/xfs/xfs_vnodeops.c4
66 files changed, 1305 insertions, 710 deletions
diff --git a/fs/Makefile b/fs/Makefile
index 414484ac48c1..2c22e282c777 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -10,7 +10,7 @@ obj-y := open.o read_write.o file_table.o buffer.o bio.o super.o \
10 ioctl.o readdir.o select.o fifo.o locks.o dcache.o inode.o \ 10 ioctl.o readdir.o select.o fifo.o locks.o dcache.o inode.o \
11 attr.o bad_inode.o file.o filesystems.o namespace.o aio.o \ 11 attr.o bad_inode.o file.o filesystems.o namespace.o aio.o \
12 seq_file.o xattr.o libfs.o fs-writeback.o mpage.o direct-io.o \ 12 seq_file.o xattr.o libfs.o fs-writeback.o mpage.o direct-io.o \
13 ioprio.o pnode.o drop_caches.o splice.o 13 ioprio.o pnode.o drop_caches.o splice.o sync.o
14 14
15obj-$(CONFIG_INOTIFY) += inotify.o 15obj-$(CONFIG_INOTIFY) += inotify.o
16obj-$(CONFIG_EPOLL) += eventpoll.o 16obj-$(CONFIG_EPOLL) += eventpoll.o
diff --git a/fs/char_dev.c b/fs/char_dev.c
index 4e1b849f912f..f3418f7a6e9d 100644
--- a/fs/char_dev.c
+++ b/fs/char_dev.c
@@ -15,6 +15,7 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/smp_lock.h> 16#include <linux/smp_lock.h>
17#include <linux/devfs_fs_kernel.h> 17#include <linux/devfs_fs_kernel.h>
18#include <linux/seq_file.h>
18 19
19#include <linux/kobject.h> 20#include <linux/kobject.h>
20#include <linux/kobj_map.h> 21#include <linux/kobj_map.h>
@@ -27,8 +28,6 @@
27 28
28static struct kobj_map *cdev_map; 29static struct kobj_map *cdev_map;
29 30
30#define MAX_PROBE_HASH 255 /* random */
31
32static DEFINE_MUTEX(chrdevs_lock); 31static DEFINE_MUTEX(chrdevs_lock);
33 32
34static struct char_device_struct { 33static struct char_device_struct {
@@ -39,93 +38,29 @@ static struct char_device_struct {
39 char name[64]; 38 char name[64];
40 struct file_operations *fops; 39 struct file_operations *fops;
41 struct cdev *cdev; /* will die */ 40 struct cdev *cdev; /* will die */
42} *chrdevs[MAX_PROBE_HASH]; 41} *chrdevs[CHRDEV_MAJOR_HASH_SIZE];
43 42
44/* index in the above */ 43/* index in the above */
45static inline int major_to_index(int major) 44static inline int major_to_index(int major)
46{ 45{
47 return major % MAX_PROBE_HASH; 46 return major % CHRDEV_MAJOR_HASH_SIZE;
48}
49
50struct chrdev_info {
51 int index;
52 struct char_device_struct *cd;
53};
54
55void *get_next_chrdev(void *dev)
56{
57 struct chrdev_info *info;
58
59 if (dev == NULL) {
60 info = kmalloc(sizeof(*info), GFP_KERNEL);
61 if (!info)
62 goto out;
63 info->index=0;
64 info->cd = chrdevs[info->index];
65 if (info->cd)
66 goto out;
67 } else {
68 info = dev;
69 }
70
71 while (info->index < ARRAY_SIZE(chrdevs)) {
72 if (info->cd)
73 info->cd = info->cd->next;
74 if (info->cd)
75 goto out;
76 /*
77 * No devices on this chain, move to the next
78 */
79 info->index++;
80 info->cd = (info->index < ARRAY_SIZE(chrdevs)) ?
81 chrdevs[info->index] : NULL;
82 if (info->cd)
83 goto out;
84 }
85
86out:
87 return info;
88}
89
90void *acquire_chrdev_list(void)
91{
92 mutex_lock(&chrdevs_lock);
93 return get_next_chrdev(NULL);
94}
95
96void release_chrdev_list(void *dev)
97{
98 mutex_unlock(&chrdevs_lock);
99 kfree(dev);
100} 47}
101 48
49#ifdef CONFIG_PROC_FS
102 50
103int count_chrdev_list(void) 51void chrdev_show(struct seq_file *f, off_t offset)
104{ 52{
105 struct char_device_struct *cd; 53 struct char_device_struct *cd;
106 int i, count;
107
108 count = 0;
109 54
110 for (i = 0; i < ARRAY_SIZE(chrdevs) ; i++) { 55 if (offset < CHRDEV_MAJOR_HASH_SIZE) {
111 for (cd = chrdevs[i]; cd; cd = cd->next) 56 mutex_lock(&chrdevs_lock);
112 count++; 57 for (cd = chrdevs[offset]; cd; cd = cd->next)
58 seq_printf(f, "%3d %s\n", cd->major, cd->name);
59 mutex_unlock(&chrdevs_lock);
113 } 60 }
114
115 return count;
116} 61}
117 62
118int get_chrdev_info(void *dev, int *major, char **name) 63#endif /* CONFIG_PROC_FS */
119{
120 struct chrdev_info *info = dev;
121
122 if (info->cd == NULL)
123 return 1;
124
125 *major = info->cd->major;
126 *name = info->cd->name;
127 return 0;
128}
129 64
130/* 65/*
131 * Register a single major with a specified minor range. 66 * Register a single major with a specified minor range.
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index cb68efba35db..8a2de038882e 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,3 +1,21 @@
1Version 1.42
2------------
3Fix slow oplock break when mounted to different servers at the same time and
4the tids match and we try to find matching fid on wrong server.
5
6Version 1.41
7------------
8Fix NTLMv2 security (can be enabled in /proc/fs/cifs) so customers can
9configure stronger authentication. Fix sfu symlinks so they can
10be followed (not just recognized). Fix wraparound of bcc on
11read responses when buffer size over 64K and also fix wrap of
12max smb buffer size when CIFSMaxBufSize over 64K. Fix oops in
13cifs_user_read and cifs_readpages (when EAGAIN on send of smb
14on socket is returned over and over). Add POSIX (advisory) byte range
15locking support (requires server with newest CIFS UNIX Extensions
16to the protocol implemented). Slow down negprot slightly in port 139
17RFC1001 case to give session_init time on buggy servers.
18
1Version 1.40 19Version 1.40
2------------ 20------------
3Use fsuid (fsgid) more consistently instead of uid (gid). Improve performance 21Use fsuid (fsgid) more consistently instead of uid (gid). Improve performance
diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile
index 7384947a0f93..58c77254a23b 100644
--- a/fs/cifs/Makefile
+++ b/fs/cifs/Makefile
@@ -3,4 +3,4 @@
3# 3#
4obj-$(CONFIG_CIFS) += cifs.o 4obj-$(CONFIG_CIFS) += cifs.o
5 5
6cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o 6cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o ntlmssp.o
diff --git a/fs/cifs/README b/fs/cifs/README
index b0070d1b149d..b2b4d0803761 100644
--- a/fs/cifs/README
+++ b/fs/cifs/README
@@ -422,6 +422,13 @@ A partial list of the supported mount options follows:
422 nomapchars Do not translate any of these seven characters (default). 422 nomapchars Do not translate any of these seven characters (default).
423 nocase Request case insensitive path name matching (case 423 nocase Request case insensitive path name matching (case
424 sensitive is the default if the server suports it). 424 sensitive is the default if the server suports it).
425 posixpaths If CIFS Unix extensions are supported, attempt to
426 negotiate posix path name support which allows certain
427 characters forbidden in typical CIFS filenames, without
428 requiring remapping. (default)
429 noposixpaths If CIFS Unix extensions are supported, do not request
430 posix path name support (this may cause servers to
431 reject creatingfile with certain reserved characters).
425 nobrl Do not send byte range lock requests to the server. 432 nobrl Do not send byte range lock requests to the server.
426 This is necessary for certain applications that break 433 This is necessary for certain applications that break
427 with cifs style mandatory byte range locks (and most 434 with cifs style mandatory byte range locks (and most
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index a2c24858d40f..e7d63737e651 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/cifsencrypt.c 2 * fs/cifs/cifsencrypt.c
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2005 4 * Copyright (C) International Business Machines Corp., 2005,2006
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
@@ -36,7 +36,8 @@
36extern void mdfour(unsigned char *out, unsigned char *in, int n); 36extern void mdfour(unsigned char *out, unsigned char *in, int n);
37extern void E_md4hash(const unsigned char *passwd, unsigned char *p16); 37extern void E_md4hash(const unsigned char *passwd, unsigned char *p16);
38 38
39static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu, const char * key, char * signature) 39static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu,
40 const char * key, char * signature)
40{ 41{
41 struct MD5Context context; 42 struct MD5Context context;
42 43
@@ -56,9 +57,6 @@ int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct TCP_Server_Info * server,
56 int rc = 0; 57 int rc = 0;
57 char smb_signature[20]; 58 char smb_signature[20];
58 59
59 /* BB remember to initialize sequence number elsewhere and initialize mac_signing key elsewhere BB */
60 /* BB remember to add code to save expected sequence number in midQ entry BB */
61
62 if((cifs_pdu == NULL) || (server == NULL)) 60 if((cifs_pdu == NULL) || (server == NULL))
63 return -EINVAL; 61 return -EINVAL;
64 62
@@ -85,20 +83,33 @@ int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct TCP_Server_Info * server,
85static int cifs_calc_signature2(const struct kvec * iov, int n_vec, 83static int cifs_calc_signature2(const struct kvec * iov, int n_vec,
86 const char * key, char * signature) 84 const char * key, char * signature)
87{ 85{
88 struct MD5Context context; 86 struct MD5Context context;
89 87 int i;
90 if((iov == NULL) || (signature == NULL))
91 return -EINVAL;
92 88
93 MD5Init(&context); 89 if((iov == NULL) || (signature == NULL))
94 MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16); 90 return -EINVAL;
95 91
96/* MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length); */ /* BB FIXME BB */ 92 MD5Init(&context);
93 MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16);
94 for(i=0;i<n_vec;i++) {
95 if(iov[i].iov_base == NULL) {
96 cERROR(1,("null iovec entry"));
97 return -EIO;
98 } else if(iov[i].iov_len == 0)
99 break; /* bail out if we are sent nothing to sign */
100 /* The first entry includes a length field (which does not get
101 signed that occupies the first 4 bytes before the header */
102 if(i==0) {
103 if (iov[0].iov_len <= 8 ) /* cmd field at offset 9 */
104 break; /* nothing to sign or corrupt header */
105 MD5Update(&context,iov[0].iov_base+4, iov[0].iov_len-4);
106 } else
107 MD5Update(&context,iov[i].iov_base, iov[i].iov_len);
108 }
97 109
98 MD5Final(signature,&context); 110 MD5Final(signature,&context);
99 111
100 return -EOPNOTSUPP; 112 return 0;
101/* return 0; */
102} 113}
103 114
104 115
@@ -259,4 +270,5 @@ void CalcNTLMv2_response(const struct cifsSesInfo * ses,char * v2_session_respon
259/* hmac_md5_update(v2_session_response+16)client thing,8,&context); */ /* BB fix */ 270/* hmac_md5_update(v2_session_response+16)client thing,8,&context); */ /* BB fix */
260 271
261 hmac_md5_final(v2_session_response,&context); 272 hmac_md5_final(v2_session_response,&context);
273 cifs_dump_mem("v2_sess_rsp: ", v2_session_response, 32); /* BB removeme BB */
262} 274}
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 4bbc544857bc..d4b713e5affb 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -93,13 +93,10 @@ cifs_read_super(struct super_block *sb, void *data,
93 int rc = 0; 93 int rc = 0;
94 94
95 sb->s_flags |= MS_NODIRATIME; /* and probably even noatime */ 95 sb->s_flags |= MS_NODIRATIME; /* and probably even noatime */
96 sb->s_fs_info = kmalloc(sizeof(struct cifs_sb_info),GFP_KERNEL); 96 sb->s_fs_info = kzalloc(sizeof(struct cifs_sb_info),GFP_KERNEL);
97 cifs_sb = CIFS_SB(sb); 97 cifs_sb = CIFS_SB(sb);
98 if(cifs_sb == NULL) 98 if(cifs_sb == NULL)
99 return -ENOMEM; 99 return -ENOMEM;
100 else
101 memset(cifs_sb,0,sizeof(struct cifs_sb_info));
102
103 100
104 rc = cifs_mount(sb, cifs_sb, data, devname); 101 rc = cifs_mount(sb, cifs_sb, data, devname);
105 102
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 74f405ae4da3..4e829dc672a6 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -99,5 +99,5 @@ extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t);
99extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); 99extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);
100extern int cifs_ioctl (struct inode * inode, struct file * filep, 100extern int cifs_ioctl (struct inode * inode, struct file * filep,
101 unsigned int command, unsigned long arg); 101 unsigned int command, unsigned long arg);
102#define CIFS_VERSION "1.40" 102#define CIFS_VERSION "1.42"
103#endif /* _CIFSFS_H */ 103#endif /* _CIFSFS_H */
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 7bed27601ce5..006eb33bff5f 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/cifsglob.h 2 * fs/cifs/cifsglob.h
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2002,2005 4 * Copyright (C) International Business Machines Corp., 2002,2006
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
@@ -430,6 +430,15 @@ struct dir_notify_req {
430#define CIFS_LARGE_BUFFER 2 430#define CIFS_LARGE_BUFFER 2
431#define CIFS_IOVEC 4 /* array of response buffers */ 431#define CIFS_IOVEC 4 /* array of response buffers */
432 432
433/* Type of session setup needed */
434#define CIFS_PLAINTEXT 0
435#define CIFS_LANMAN 1
436#define CIFS_NTLM 2
437#define CIFS_NTLMSSP_NEG 3
438#define CIFS_NTLMSSP_AUTH 4
439#define CIFS_SPNEGO_INIT 5
440#define CIFS_SPNEGO_TARG 6
441
433/* 442/*
434 ***************************************************************** 443 *****************************************************************
435 * All constants go here 444 * All constants go here
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index cc2471094ca5..b2233ac05bd2 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -859,7 +859,10 @@ typedef struct smb_com_lock_req {
859 LOCKING_ANDX_RANGE Locks[1]; 859 LOCKING_ANDX_RANGE Locks[1];
860} __attribute__((packed)) LOCK_REQ; 860} __attribute__((packed)) LOCK_REQ;
861 861
862 862/* lock type */
863#define CIFS_RDLCK 0
864#define CIFS_WRLCK 1
865#define CIFS_UNLCK 2
863typedef struct cifs_posix_lock { 866typedef struct cifs_posix_lock {
864 __le16 lock_type; /* 0 = Read, 1 = Write, 2 = Unlock */ 867 __le16 lock_type; /* 0 = Read, 1 = Write, 2 = Unlock */
865 __le16 lock_flags; /* 1 = Wait (only valid for setlock) */ 868 __le16 lock_flags; /* 1 = Wait (only valid for setlock) */
@@ -1786,7 +1789,13 @@ typedef struct {
1786#define CIFS_UNIX_POSIX_ACL_CAP 0x00000002 /* support getfacl/setfacl */ 1789#define CIFS_UNIX_POSIX_ACL_CAP 0x00000002 /* support getfacl/setfacl */
1787#define CIFS_UNIX_XATTR_CAP 0x00000004 /* support new namespace */ 1790#define CIFS_UNIX_XATTR_CAP 0x00000004 /* support new namespace */
1788#define CIFS_UNIX_EXTATTR_CAP 0x00000008 /* support chattr/chflag */ 1791#define CIFS_UNIX_EXTATTR_CAP 0x00000008 /* support chattr/chflag */
1789#define CIFS_UNIX_POSIX_PATHNAMES_CAP 0x00000010 /* Use POSIX pathnames on the wire. */ 1792#define CIFS_UNIX_POSIX_PATHNAMES_CAP 0x00000010 /* Allow POSIX path chars */
1793#ifdef CONFIG_CIFS_POSIX
1794#define CIFS_UNIX_CAP_MASK 0x0000001b
1795#else
1796#define CIFS_UNIX_CAP_MASK 0x00000013
1797#endif /* CONFIG_CIFS_POSIX */
1798
1790 1799
1791#define CIFS_POSIX_EXTENSIONS 0x00000010 /* support for new QFSInfo */ 1800#define CIFS_POSIX_EXTENSIONS 0x00000010 /* support for new QFSInfo */
1792 1801
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 7b25463d3c14..2879ba343ca7 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/cifsproto.h 2 * fs/cifs/cifsproto.h
3 * 3 *
4 * Copyright (c) International Business Machines Corp., 2002,2005 4 * Copyright (c) International Business Machines Corp., 2002,2006
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
@@ -64,6 +64,14 @@ extern int map_smb_to_linux_error(struct smb_hdr *smb);
64extern void header_assemble(struct smb_hdr *, char /* command */ , 64extern void header_assemble(struct smb_hdr *, char /* command */ ,
65 const struct cifsTconInfo *, int /* length of 65 const struct cifsTconInfo *, int /* length of
66 fixed section (word count) in two byte units */); 66 fixed section (word count) in two byte units */);
67#ifdef CONFIG_CIFS_EXPERIMENTAL
68extern int small_smb_init_no_tc(const int smb_cmd, const int wct,
69 struct cifsSesInfo *ses,
70 void ** request_buf);
71extern int CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
72 const int stage, int * pNTLMv2_flg,
73 const struct nls_table *nls_cp);
74#endif
67extern __u16 GetNextMid(struct TCP_Server_Info *server); 75extern __u16 GetNextMid(struct TCP_Server_Info *server);
68extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16, 76extern struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16,
69 struct cifsTconInfo *); 77 struct cifsTconInfo *);
@@ -257,7 +265,10 @@ extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
257 const __u64 offset, const __u32 numUnlock, 265 const __u64 offset, const __u32 numUnlock,
258 const __u32 numLock, const __u8 lockType, 266 const __u32 numLock, const __u8 lockType,
259 const int waitFlag); 267 const int waitFlag);
260 268extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
269 const __u16 smb_file_id, const int get_flag,
270 const __u64 len, const __u64 offset,
271 const __u16 lock_type, const int waitFlag);
261extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon); 272extern int CIFSSMBTDis(const int xid, struct cifsTconInfo *tcon);
262extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses); 273extern int CIFSSMBLogoff(const int xid, struct cifsSesInfo *ses);
263 274
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index a243fe2792d5..d705500aa283 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/cifssmb.c 2 * fs/cifs/cifssmb.c
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2002,2005 4 * Copyright (C) International Business Machines Corp., 2002,2006
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * Contains the routines for constructing the SMB PDUs themselves 7 * Contains the routines for constructing the SMB PDUs themselves
@@ -186,7 +186,35 @@ small_smb_init(int smb_command, int wct, struct cifsTconInfo *tcon,
186 cifs_stats_inc(&tcon->num_smbs_sent); 186 cifs_stats_inc(&tcon->num_smbs_sent);
187 187
188 return rc; 188 return rc;
189} 189}
190
191#ifdef CONFIG_CIFS_EXPERIMENTAL
192int
193small_smb_init_no_tc(const int smb_command, const int wct,
194 struct cifsSesInfo *ses, void **request_buf)
195{
196 int rc;
197 struct smb_hdr * buffer;
198
199 rc = small_smb_init(smb_command, wct, NULL, request_buf);
200 if(rc)
201 return rc;
202
203 buffer = (struct smb_hdr *)*request_buf;
204 buffer->Mid = GetNextMid(ses->server);
205 if (ses->capabilities & CAP_UNICODE)
206 buffer->Flags2 |= SMBFLG2_UNICODE;
207 if (ses->capabilities & CAP_STATUS32)
208 buffer->Flags2 |= SMBFLG2_ERR_STATUS;
209
210 /* uid, tid can stay at zero as set in header assemble */
211
212 /* BB add support for turning on the signing when
213 this function is used after 1st of session setup requests */
214
215 return rc;
216}
217#endif /* CONFIG_CIFS_EXPERIMENTAL */
190 218
191/* If the return code is zero, this function must fill in request_buf pointer */ 219/* If the return code is zero, this function must fill in request_buf pointer */
192static int 220static int
@@ -1042,7 +1070,7 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
1042 } 1070 }
1043 } 1071 }
1044 1072
1045 cifs_small_buf_release(pSMB); 1073/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
1046 if(*buf) { 1074 if(*buf) {
1047 if(resp_buf_type == CIFS_SMALL_BUFFER) 1075 if(resp_buf_type == CIFS_SMALL_BUFFER)
1048 cifs_small_buf_release(iov[0].iov_base); 1076 cifs_small_buf_release(iov[0].iov_base);
@@ -1246,7 +1274,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1246 *nbytes += le16_to_cpu(pSMBr->Count); 1274 *nbytes += le16_to_cpu(pSMBr->Count);
1247 } 1275 }
1248 1276
1249 cifs_small_buf_release(pSMB); 1277/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
1250 if(resp_buf_type == CIFS_SMALL_BUFFER) 1278 if(resp_buf_type == CIFS_SMALL_BUFFER)
1251 cifs_small_buf_release(iov[0].iov_base); 1279 cifs_small_buf_release(iov[0].iov_base);
1252 else if(resp_buf_type == CIFS_LARGE_BUFFER) 1280 else if(resp_buf_type == CIFS_LARGE_BUFFER)
@@ -1325,6 +1353,85 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
1325} 1353}
1326 1354
1327int 1355int
1356CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1357 const __u16 smb_file_id, const int get_flag, const __u64 len,
1358 const __u64 lkoffset, const __u16 lock_type, const int waitFlag)
1359{
1360 struct smb_com_transaction2_sfi_req *pSMB = NULL;
1361 struct smb_com_transaction2_sfi_rsp *pSMBr = NULL;
1362 char *data_offset;
1363 struct cifs_posix_lock *parm_data;
1364 int rc = 0;
1365 int bytes_returned = 0;
1366 __u16 params, param_offset, offset, byte_count, count;
1367
1368 cFYI(1, ("Posix Lock"));
1369 rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);
1370
1371 if (rc)
1372 return rc;
1373
1374 pSMBr = (struct smb_com_transaction2_sfi_rsp *)pSMB;
1375
1376 params = 6;
1377 pSMB->MaxSetupCount = 0;
1378 pSMB->Reserved = 0;
1379 pSMB->Flags = 0;
1380 pSMB->Timeout = 0;
1381 pSMB->Reserved2 = 0;
1382 param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
1383 offset = param_offset + params;
1384
1385 data_offset = (char *) (&pSMB->hdr.Protocol) + offset;
1386
1387 count = sizeof(struct cifs_posix_lock);
1388 pSMB->MaxParameterCount = cpu_to_le16(2);
1389 pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */
1390 pSMB->SetupCount = 1;
1391 pSMB->Reserved3 = 0;
1392 if(get_flag)
1393 pSMB->SubCommand = cpu_to_le16(TRANS2_QUERY_FILE_INFORMATION);
1394 else
1395 pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
1396 byte_count = 3 /* pad */ + params + count;
1397 pSMB->DataCount = cpu_to_le16(count);
1398 pSMB->ParameterCount = cpu_to_le16(params);
1399 pSMB->TotalDataCount = pSMB->DataCount;
1400 pSMB->TotalParameterCount = pSMB->ParameterCount;
1401 pSMB->ParameterOffset = cpu_to_le16(param_offset);
1402 parm_data = (struct cifs_posix_lock *)
1403 (((char *) &pSMB->hdr.Protocol) + offset);
1404
1405 parm_data->lock_type = cpu_to_le16(lock_type);
1406 if(waitFlag)
1407 parm_data->lock_flags = 1;
1408 parm_data->pid = cpu_to_le32(current->tgid);
1409 parm_data->start = lkoffset;
1410 parm_data->length = len; /* normalize negative numbers */
1411
1412 pSMB->DataOffset = cpu_to_le16(offset);
1413 pSMB->Fid = smb_file_id;
1414 pSMB->InformationLevel = cpu_to_le16(SMB_SET_POSIX_LOCK);
1415 pSMB->Reserved4 = 0;
1416 pSMB->hdr.smb_buf_length += byte_count;
1417 pSMB->ByteCount = cpu_to_le16(byte_count);
1418 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
1419 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
1420 if (rc) {
1421 cFYI(1, ("Send error in Posix Lock = %d", rc));
1422 }
1423
1424 if (pSMB)
1425 cifs_small_buf_release(pSMB);
1426
1427 /* Note: On -EAGAIN error only caller can retry on handle based calls
1428 since file handle passed in no longer valid */
1429
1430 return rc;
1431}
1432
1433
1434int
1328CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id) 1435CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
1329{ 1436{
1330 int rc = 0; 1437 int rc = 0;
@@ -2578,7 +2685,7 @@ qsec_out:
2578 cifs_small_buf_release(iov[0].iov_base); 2685 cifs_small_buf_release(iov[0].iov_base);
2579 else if(buf_type == CIFS_LARGE_BUFFER) 2686 else if(buf_type == CIFS_LARGE_BUFFER)
2580 cifs_buf_release(iov[0].iov_base); 2687 cifs_buf_release(iov[0].iov_base);
2581 cifs_small_buf_release(pSMB); 2688/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
2582 return rc; 2689 return rc;
2583} 2690}
2584 2691
@@ -2954,7 +3061,8 @@ findFirstRetry:
2954 pSMB->TotalParameterCount = cpu_to_le16(params); 3061 pSMB->TotalParameterCount = cpu_to_le16(params);
2955 pSMB->ParameterCount = pSMB->TotalParameterCount; 3062 pSMB->ParameterCount = pSMB->TotalParameterCount;
2956 pSMB->ParameterOffset = cpu_to_le16( 3063 pSMB->ParameterOffset = cpu_to_le16(
2957 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes) - 4); 3064 offsetof(struct smb_com_transaction2_ffirst_req, SearchAttributes)
3065 - 4);
2958 pSMB->DataCount = 0; 3066 pSMB->DataCount = 0;
2959 pSMB->DataOffset = 0; 3067 pSMB->DataOffset = 0;
2960 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */ 3068 pSMB->SetupCount = 1; /* one byte, no need to make endian neutral */
@@ -2977,12 +3085,12 @@ findFirstRetry:
2977 (struct smb_hdr *) pSMBr, &bytes_returned, 0); 3085 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2978 cifs_stats_inc(&tcon->num_ffirst); 3086 cifs_stats_inc(&tcon->num_ffirst);
2979 3087
2980 if (rc) {/* BB add logic to retry regular search if Unix search rejected unexpectedly by server */ 3088 if (rc) {/* BB add logic to retry regular search if Unix search
3089 rejected unexpectedly by server */
2981 /* BB Add code to handle unsupported level rc */ 3090 /* BB Add code to handle unsupported level rc */
2982 cFYI(1, ("Error in FindFirst = %d", rc)); 3091 cFYI(1, ("Error in FindFirst = %d", rc));
2983 3092
2984 if (pSMB) 3093 cifs_buf_release(pSMB);
2985 cifs_buf_release(pSMB);
2986 3094
2987 /* BB eventually could optimize out free and realloc of buf */ 3095 /* BB eventually could optimize out free and realloc of buf */
2988 /* for this case */ 3096 /* for this case */
@@ -2998,6 +3106,7 @@ findFirstRetry:
2998 psrch_inf->unicode = FALSE; 3106 psrch_inf->unicode = FALSE;
2999 3107
3000 psrch_inf->ntwrk_buf_start = (char *)pSMBr; 3108 psrch_inf->ntwrk_buf_start = (char *)pSMBr;
3109 psrch_inf->smallBuf = 0;
3001 psrch_inf->srch_entries_start = 3110 psrch_inf->srch_entries_start =
3002 (char *) &pSMBr->hdr.Protocol + 3111 (char *) &pSMBr->hdr.Protocol +
3003 le16_to_cpu(pSMBr->t2.DataOffset); 3112 le16_to_cpu(pSMBr->t2.DataOffset);
@@ -3118,9 +3227,14 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
3118 parms = (T2_FNEXT_RSP_PARMS *)response_data; 3227 parms = (T2_FNEXT_RSP_PARMS *)response_data;
3119 response_data = (char *)&pSMBr->hdr.Protocol + 3228 response_data = (char *)&pSMBr->hdr.Protocol +
3120 le16_to_cpu(pSMBr->t2.DataOffset); 3229 le16_to_cpu(pSMBr->t2.DataOffset);
3121 cifs_buf_release(psrch_inf->ntwrk_buf_start); 3230 if(psrch_inf->smallBuf)
3231 cifs_small_buf_release(
3232 psrch_inf->ntwrk_buf_start);
3233 else
3234 cifs_buf_release(psrch_inf->ntwrk_buf_start);
3122 psrch_inf->srch_entries_start = response_data; 3235 psrch_inf->srch_entries_start = response_data;
3123 psrch_inf->ntwrk_buf_start = (char *)pSMB; 3236 psrch_inf->ntwrk_buf_start = (char *)pSMB;
3237 psrch_inf->smallBuf = 0;
3124 if(parms->EndofSearch) 3238 if(parms->EndofSearch)
3125 psrch_inf->endOfSearch = TRUE; 3239 psrch_inf->endOfSearch = TRUE;
3126 else 3240 else
@@ -3834,6 +3948,7 @@ CIFSSMBSetFSUnixInfo(const int xid, struct cifsTconInfo *tcon, __u64 cap)
3834 3948
3835 cFYI(1, ("In SETFSUnixInfo")); 3949 cFYI(1, ("In SETFSUnixInfo"));
3836SETFSUnixRetry: 3950SETFSUnixRetry:
3951 /* BB switch to small buf init to save memory */
3837 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, 3952 rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB,
3838 (void **) &pSMBr); 3953 (void **) &pSMBr);
3839 if (rc) 3954 if (rc)
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 2a0c1f4ca0ae..0b86d5ca9014 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/connect.c 2 * fs/cifs/connect.c
3 * 3 *
4 * Copyright (C) International Business Machines Corp., 2002,2005 4 * Copyright (C) International Business Machines Corp., 2002,2006
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
@@ -564,7 +564,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
564 564
565 565
566 dump_smb(smb_buffer, length); 566 dump_smb(smb_buffer, length);
567 if (checkSMB (smb_buffer, smb_buffer->Mid, total_read+4)) { 567 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) {
568 cifs_dump_mem("Bad SMB: ", smb_buffer, 48); 568 cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
569 continue; 569 continue;
570 } 570 }
@@ -1476,6 +1476,14 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1476 rc = smb_send(*csocket, smb_buf, 0x44, 1476 rc = smb_send(*csocket, smb_buf, 0x44,
1477 (struct sockaddr *)psin_server); 1477 (struct sockaddr *)psin_server);
1478 kfree(ses_init_buf); 1478 kfree(ses_init_buf);
1479 msleep(1); /* RFC1001 layer in at least one server
1480 requires very short break before negprot
1481 presumably because not expecting negprot
1482 to follow so fast. This is a simple
1483 solution that works without
1484 complicating the code and causes no
1485 significant slowing down on mount
1486 for everyone else */
1479 } 1487 }
1480 /* else the negprot may still work without this 1488 /* else the negprot may still work without this
1481 even though malloc failed */ 1489 even though malloc failed */
@@ -1920,27 +1928,34 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1920 cifs_sb->tcon = tcon; 1928 cifs_sb->tcon = tcon;
1921 tcon->ses = pSesInfo; 1929 tcon->ses = pSesInfo;
1922 1930
1923 /* do not care if following two calls succeed - informational only */ 1931 /* do not care if following two calls succeed - informational */
1924 CIFSSMBQFSDeviceInfo(xid, tcon); 1932 CIFSSMBQFSDeviceInfo(xid, tcon);
1925 CIFSSMBQFSAttributeInfo(xid, tcon); 1933 CIFSSMBQFSAttributeInfo(xid, tcon);
1934
1926 if (tcon->ses->capabilities & CAP_UNIX) { 1935 if (tcon->ses->capabilities & CAP_UNIX) {
1927 if(!CIFSSMBQFSUnixInfo(xid, tcon)) { 1936 if(!CIFSSMBQFSUnixInfo(xid, tcon)) {
1928 if(!volume_info.no_psx_acl) { 1937 __u64 cap =
1929 if(CIFS_UNIX_POSIX_ACL_CAP & 1938 le64_to_cpu(tcon->fsUnixInfo.Capability);
1930 le64_to_cpu(tcon->fsUnixInfo.Capability)) 1939 cap &= CIFS_UNIX_CAP_MASK;
1931 cFYI(1,("server negotiated posix acl support")); 1940 if(volume_info.no_psx_acl)
1932 sb->s_flags |= MS_POSIXACL; 1941 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1942 else if(CIFS_UNIX_POSIX_ACL_CAP & cap) {
1943 cFYI(1,("negotiated posix acl support"));
1944 sb->s_flags |= MS_POSIXACL;
1933 } 1945 }
1934 1946
1935 /* Try and negotiate POSIX pathnames if we can. */ 1947 if(volume_info.posix_paths == 0)
1936 if (volume_info.posix_paths && (CIFS_UNIX_POSIX_PATHNAMES_CAP & 1948 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1937 le64_to_cpu(tcon->fsUnixInfo.Capability))) { 1949 else if(cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
1938 if (!CIFSSMBSetFSUnixInfo(xid, tcon, CIFS_UNIX_POSIX_PATHNAMES_CAP)) { 1950 cFYI(1,("negotiate posix pathnames"));
1939 cFYI(1,("negotiated posix pathnames support")); 1951 cifs_sb->mnt_cifs_flags |=
1940 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS; 1952 CIFS_MOUNT_POSIX_PATHS;
1941 } else { 1953 }
1942 cFYI(1,("posix pathnames support requested but not supported")); 1954
1943 } 1955 cFYI(1,("Negotiate caps 0x%x",(int)cap));
1956
1957 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
1958 cFYI(1,("setting capabilities failed"));
1944 } 1959 }
1945 } 1960 }
1946 } 1961 }
@@ -2278,6 +2293,8 @@ CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2278 smb_buffer->Mid = GetNextMid(ses->server); 2293 smb_buffer->Mid = GetNextMid(ses->server);
2279 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC; 2294 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2280 pSMB->req.AndXCommand = 0xFF; 2295 pSMB->req.AndXCommand = 0xFF;
2296 if(ses->server->maxBuf > 64*1024)
2297 ses->server->maxBuf = (64*1023);
2281 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf); 2298 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2282 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq); 2299 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2283 2300
@@ -2525,7 +2542,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2525 __u32 negotiate_flags, capabilities; 2542 __u32 negotiate_flags, capabilities;
2526 __u16 count; 2543 __u16 count;
2527 2544
2528 cFYI(1, ("In NTLMSSP sesssetup (negotiate) ")); 2545 cFYI(1, ("In NTLMSSP sesssetup (negotiate)"));
2529 if(ses == NULL) 2546 if(ses == NULL)
2530 return -EINVAL; 2547 return -EINVAL;
2531 domain = ses->domainName; 2548 domain = ses->domainName;
@@ -2575,7 +2592,8 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2575 SecurityBlob->MessageType = NtLmNegotiate; 2592 SecurityBlob->MessageType = NtLmNegotiate;
2576 negotiate_flags = 2593 negotiate_flags =
2577 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM | 2594 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
2578 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | 0x80000000 | 2595 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM |
2596 NTLMSSP_NEGOTIATE_56 |
2579 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128; 2597 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
2580 if(sign_CIFS_PDUs) 2598 if(sign_CIFS_PDUs)
2581 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN; 2599 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
@@ -2588,26 +2606,11 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2588 SecurityBlob->WorkstationName.Length = 0; 2606 SecurityBlob->WorkstationName.Length = 0;
2589 SecurityBlob->WorkstationName.MaximumLength = 0; 2607 SecurityBlob->WorkstationName.MaximumLength = 0;
2590 2608
2591 if (domain == NULL) { 2609 /* Domain not sent on first Sesssetup in NTLMSSP, instead it is sent
2592 SecurityBlob->DomainName.Buffer = 0; 2610 along with username on auth request (ie the response to challenge) */
2593 SecurityBlob->DomainName.Length = 0; 2611 SecurityBlob->DomainName.Buffer = 0;
2594 SecurityBlob->DomainName.MaximumLength = 0; 2612 SecurityBlob->DomainName.Length = 0;
2595 } else { 2613 SecurityBlob->DomainName.MaximumLength = 0;
2596 __u16 len;
2597 negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
2598 strncpy(bcc_ptr, domain, 63);
2599 len = strnlen(domain, 64);
2600 SecurityBlob->DomainName.MaximumLength =
2601 cpu_to_le16(len);
2602 SecurityBlob->DomainName.Buffer =
2603 cpu_to_le32((long) &SecurityBlob->
2604 DomainString -
2605 (long) &SecurityBlob->Signature);
2606 bcc_ptr += len;
2607 SecurityBlobLength += len;
2608 SecurityBlob->DomainName.Length =
2609 cpu_to_le16(len);
2610 }
2611 if (ses->capabilities & CAP_UNICODE) { 2614 if (ses->capabilities & CAP_UNICODE) {
2612 if ((long) bcc_ptr % 2) { 2615 if ((long) bcc_ptr % 2) {
2613 *bcc_ptr = 0; 2616 *bcc_ptr = 0;
@@ -2677,7 +2680,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2677 SecurityBlob2->MessageType)); 2680 SecurityBlob2->MessageType));
2678 } else if (ses) { 2681 } else if (ses) {
2679 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */ 2682 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
2680 cFYI(1, ("UID = %d ", ses->Suid)); 2683 cFYI(1, ("UID = %d", ses->Suid));
2681 if ((pSMBr->resp.hdr.WordCount == 3) 2684 if ((pSMBr->resp.hdr.WordCount == 3)
2682 || ((pSMBr->resp.hdr.WordCount == 4) 2685 || ((pSMBr->resp.hdr.WordCount == 4)
2683 && (blob_len < 2686 && (blob_len <
@@ -2685,17 +2688,17 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2685 2688
2686 if (pSMBr->resp.hdr.WordCount == 4) { 2689 if (pSMBr->resp.hdr.WordCount == 4) {
2687 bcc_ptr += blob_len; 2690 bcc_ptr += blob_len;
2688 cFYI(1, 2691 cFYI(1, ("Security Blob Length %d",
2689 ("Security Blob Length %d ",
2690 blob_len)); 2692 blob_len));
2691 } 2693 }
2692 2694
2693 cFYI(1, ("NTLMSSP Challenge rcvd ")); 2695 cFYI(1, ("NTLMSSP Challenge rcvd"));
2694 2696
2695 memcpy(ses->server->cryptKey, 2697 memcpy(ses->server->cryptKey,
2696 SecurityBlob2->Challenge, 2698 SecurityBlob2->Challenge,
2697 CIFS_CRYPTO_KEY_SIZE); 2699 CIFS_CRYPTO_KEY_SIZE);
2698 if(SecurityBlob2->NegotiateFlags & cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2)) 2700 if(SecurityBlob2->NegotiateFlags &
2701 cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
2699 *pNTLMv2_flag = TRUE; 2702 *pNTLMv2_flag = TRUE;
2700 2703
2701 if((SecurityBlob2->NegotiateFlags & 2704 if((SecurityBlob2->NegotiateFlags &
@@ -2818,7 +2821,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2818 bcc_ptr++; 2821 bcc_ptr++;
2819 } else 2822 } else
2820 cFYI(1, 2823 cFYI(1,
2821 ("Variable field of length %d extends beyond end of smb ", 2824 ("Variable field of length %d extends beyond end of smb",
2822 len)); 2825 len));
2823 } 2826 }
2824 } else { 2827 } else {
@@ -2830,7 +2833,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2830 } 2833 }
2831 } else { 2834 } else {
2832 cERROR(1, 2835 cERROR(1,
2833 (" Invalid Word count %d: ", 2836 (" Invalid Word count %d:",
2834 smb_buffer_response->WordCount)); 2837 smb_buffer_response->WordCount));
2835 rc = -EIO; 2838 rc = -EIO;
2836 } 2839 }
@@ -3447,7 +3450,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3447 if (extended_security 3450 if (extended_security
3448 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) 3451 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3449 && (pSesInfo->server->secType == NTLMSSP)) { 3452 && (pSesInfo->server->secType == NTLMSSP)) {
3450 cFYI(1, ("New style sesssetup ")); 3453 cFYI(1, ("New style sesssetup"));
3451 rc = CIFSSpnegoSessSetup(xid, pSesInfo, 3454 rc = CIFSSpnegoSessSetup(xid, pSesInfo,
3452 NULL /* security blob */, 3455 NULL /* security blob */,
3453 0 /* blob length */, 3456 0 /* blob length */,
@@ -3455,7 +3458,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3455 } else if (extended_security 3458 } else if (extended_security
3456 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) 3459 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3457 && (pSesInfo->server->secType == RawNTLMSSP)) { 3460 && (pSesInfo->server->secType == RawNTLMSSP)) {
3458 cFYI(1, ("NTLMSSP sesssetup ")); 3461 cFYI(1, ("NTLMSSP sesssetup"));
3459 rc = CIFSNTLMSSPNegotiateSessSetup(xid, 3462 rc = CIFSNTLMSSPNegotiateSessSetup(xid,
3460 pSesInfo, 3463 pSesInfo,
3461 &ntlmv2_flag, 3464 &ntlmv2_flag,
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 632561dd9c50..1d0ca3eaaca5 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -48,13 +48,14 @@ build_path_from_dentry(struct dentry *direntry)
48 struct dentry *temp; 48 struct dentry *temp;
49 int namelen = 0; 49 int namelen = 0;
50 char *full_path; 50 char *full_path;
51 char dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb)); 51 char dirsep;
52 52
53 if(direntry == NULL) 53 if(direntry == NULL)
54 return NULL; /* not much we can do if dentry is freed and 54 return NULL; /* not much we can do if dentry is freed and
55 we need to reopen the file after it was closed implicitly 55 we need to reopen the file after it was closed implicitly
56 when the server crashed */ 56 when the server crashed */
57 57
58 dirsep = CIFS_DIR_SEP(CIFS_SB(direntry->d_sb));
58cifs_bp_rename_retry: 59cifs_bp_rename_retry:
59 for (temp = direntry; !IS_ROOT(temp);) { 60 for (temp = direntry; !IS_ROOT(temp);) {
60 namelen += (1 + temp->d_name.len); 61 namelen += (1 + temp->d_name.len);
@@ -255,12 +256,10 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
255 CIFSSMBClose(xid, pTcon, fileHandle); 256 CIFSSMBClose(xid, pTcon, fileHandle);
256 } else if(newinode) { 257 } else if(newinode) {
257 pCifsFile = 258 pCifsFile =
258 kmalloc(sizeof (struct cifsFileInfo), GFP_KERNEL); 259 kzalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
259 260
260 if(pCifsFile == NULL) 261 if(pCifsFile == NULL)
261 goto cifs_create_out; 262 goto cifs_create_out;
262 memset((char *)pCifsFile, 0,
263 sizeof (struct cifsFileInfo));
264 pCifsFile->netfid = fileHandle; 263 pCifsFile->netfid = fileHandle;
265 pCifsFile->pid = current->tgid; 264 pCifsFile->pid = current->tgid;
266 pCifsFile->pInode = newinode; 265 pCifsFile->pInode = newinode;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index fb49aef1f2ec..5c497c529772 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -555,7 +555,10 @@ int cifs_closedir(struct inode *inode, struct file *file)
555 if (ptmp) { 555 if (ptmp) {
556 cFYI(1, ("closedir free smb buf in srch struct")); 556 cFYI(1, ("closedir free smb buf in srch struct"));
557 pCFileStruct->srch_inf.ntwrk_buf_start = NULL; 557 pCFileStruct->srch_inf.ntwrk_buf_start = NULL;
558 cifs_buf_release(ptmp); 558 if(pCFileStruct->srch_inf.smallBuf)
559 cifs_small_buf_release(ptmp);
560 else
561 cifs_buf_release(ptmp);
559 } 562 }
560 ptmp = pCFileStruct->search_resume_name; 563 ptmp = pCFileStruct->search_resume_name;
561 if (ptmp) { 564 if (ptmp) {
@@ -574,13 +577,14 @@ int cifs_closedir(struct inode *inode, struct file *file)
574int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) 577int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
575{ 578{
576 int rc, xid; 579 int rc, xid;
577 __u32 lockType = LOCKING_ANDX_LARGE_FILES;
578 __u32 numLock = 0; 580 __u32 numLock = 0;
579 __u32 numUnlock = 0; 581 __u32 numUnlock = 0;
580 __u64 length; 582 __u64 length;
581 int wait_flag = FALSE; 583 int wait_flag = FALSE;
582 struct cifs_sb_info *cifs_sb; 584 struct cifs_sb_info *cifs_sb;
583 struct cifsTconInfo *pTcon; 585 struct cifsTconInfo *pTcon;
586 __u16 netfid;
587 __u8 lockType = LOCKING_ANDX_LARGE_FILES;
584 588
585 length = 1 + pfLock->fl_end - pfLock->fl_start; 589 length = 1 + pfLock->fl_end - pfLock->fl_start;
586 rc = -EACCES; 590 rc = -EACCES;
@@ -592,11 +596,11 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
592 pfLock->fl_end)); 596 pfLock->fl_end));
593 597
594 if (pfLock->fl_flags & FL_POSIX) 598 if (pfLock->fl_flags & FL_POSIX)
595 cFYI(1, ("Posix ")); 599 cFYI(1, ("Posix"));
596 if (pfLock->fl_flags & FL_FLOCK) 600 if (pfLock->fl_flags & FL_FLOCK)
597 cFYI(1, ("Flock ")); 601 cFYI(1, ("Flock"));
598 if (pfLock->fl_flags & FL_SLEEP) { 602 if (pfLock->fl_flags & FL_SLEEP) {
599 cFYI(1, ("Blocking lock ")); 603 cFYI(1, ("Blocking lock"));
600 wait_flag = TRUE; 604 wait_flag = TRUE;
601 } 605 }
602 if (pfLock->fl_flags & FL_ACCESS) 606 if (pfLock->fl_flags & FL_ACCESS)
@@ -612,21 +616,23 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
612 cFYI(1, ("F_WRLCK ")); 616 cFYI(1, ("F_WRLCK "));
613 numLock = 1; 617 numLock = 1;
614 } else if (pfLock->fl_type == F_UNLCK) { 618 } else if (pfLock->fl_type == F_UNLCK) {
615 cFYI(1, ("F_UNLCK ")); 619 cFYI(1, ("F_UNLCK"));
616 numUnlock = 1; 620 numUnlock = 1;
621 /* Check if unlock includes more than
622 one lock range */
617 } else if (pfLock->fl_type == F_RDLCK) { 623 } else if (pfLock->fl_type == F_RDLCK) {
618 cFYI(1, ("F_RDLCK ")); 624 cFYI(1, ("F_RDLCK"));
619 lockType |= LOCKING_ANDX_SHARED_LOCK; 625 lockType |= LOCKING_ANDX_SHARED_LOCK;
620 numLock = 1; 626 numLock = 1;
621 } else if (pfLock->fl_type == F_EXLCK) { 627 } else if (pfLock->fl_type == F_EXLCK) {
622 cFYI(1, ("F_EXLCK ")); 628 cFYI(1, ("F_EXLCK"));
623 numLock = 1; 629 numLock = 1;
624 } else if (pfLock->fl_type == F_SHLCK) { 630 } else if (pfLock->fl_type == F_SHLCK) {
625 cFYI(1, ("F_SHLCK ")); 631 cFYI(1, ("F_SHLCK"));
626 lockType |= LOCKING_ANDX_SHARED_LOCK; 632 lockType |= LOCKING_ANDX_SHARED_LOCK;
627 numLock = 1; 633 numLock = 1;
628 } else 634 } else
629 cFYI(1, ("Unknown type of lock ")); 635 cFYI(1, ("Unknown type of lock"));
630 636
631 cifs_sb = CIFS_SB(file->f_dentry->d_sb); 637 cifs_sb = CIFS_SB(file->f_dentry->d_sb);
632 pTcon = cifs_sb->tcon; 638 pTcon = cifs_sb->tcon;
@@ -635,27 +641,41 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
635 FreeXid(xid); 641 FreeXid(xid);
636 return -EBADF; 642 return -EBADF;
637 } 643 }
644 netfid = ((struct cifsFileInfo *)file->private_data)->netfid;
645
638 646
647 /* BB add code here to normalize offset and length to
648 account for negative length which we can not accept over the
649 wire */
639 if (IS_GETLK(cmd)) { 650 if (IS_GETLK(cmd)) {
640 rc = CIFSSMBLock(xid, pTcon, 651 if(experimEnabled &&
641 ((struct cifsFileInfo *)file-> 652 (cifs_sb->tcon->ses->capabilities & CAP_UNIX) &&
642 private_data)->netfid, 653 (CIFS_UNIX_FCNTL_CAP &
643 length, 654 le64_to_cpu(cifs_sb->tcon->fsUnixInfo.Capability))) {
644 pfLock->fl_start, 0, 1, lockType, 655 int posix_lock_type;
645 0 /* wait flag */ ); 656 if(lockType & LOCKING_ANDX_SHARED_LOCK)
657 posix_lock_type = CIFS_RDLCK;
658 else
659 posix_lock_type = CIFS_WRLCK;
660 rc = CIFSSMBPosixLock(xid, pTcon, netfid, 1 /* get */,
661 length, pfLock->fl_start,
662 posix_lock_type, wait_flag);
663 FreeXid(xid);
664 return rc;
665 }
666
667 /* BB we could chain these into one lock request BB */
668 rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start,
669 0, 1, lockType, 0 /* wait flag */ );
646 if (rc == 0) { 670 if (rc == 0) {
647 rc = CIFSSMBLock(xid, pTcon, 671 rc = CIFSSMBLock(xid, pTcon, netfid, length,
648 ((struct cifsFileInfo *) file->
649 private_data)->netfid,
650 length,
651 pfLock->fl_start, 1 /* numUnlock */ , 672 pfLock->fl_start, 1 /* numUnlock */ ,
652 0 /* numLock */ , lockType, 673 0 /* numLock */ , lockType,
653 0 /* wait flag */ ); 674 0 /* wait flag */ );
654 pfLock->fl_type = F_UNLCK; 675 pfLock->fl_type = F_UNLCK;
655 if (rc != 0) 676 if (rc != 0)
656 cERROR(1, ("Error unlocking previously locked " 677 cERROR(1, ("Error unlocking previously locked "
657 "range %d during test of lock ", 678 "range %d during test of lock", rc));
658 rc));
659 rc = 0; 679 rc = 0;
660 680
661 } else { 681 } else {
@@ -667,12 +687,30 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
667 FreeXid(xid); 687 FreeXid(xid);
668 return rc; 688 return rc;
669 } 689 }
670 690 if (experimEnabled &&
671 rc = CIFSSMBLock(xid, pTcon, 691 (cifs_sb->tcon->ses->capabilities & CAP_UNIX) &&
672 ((struct cifsFileInfo *) file->private_data)-> 692 (CIFS_UNIX_FCNTL_CAP &
673 netfid, length, 693 le64_to_cpu(cifs_sb->tcon->fsUnixInfo.Capability))) {
674 pfLock->fl_start, numUnlock, numLock, lockType, 694 int posix_lock_type;
675 wait_flag); 695 if(lockType & LOCKING_ANDX_SHARED_LOCK)
696 posix_lock_type = CIFS_RDLCK;
697 else
698 posix_lock_type = CIFS_WRLCK;
699
700 if(numUnlock == 1)
701 posix_lock_type = CIFS_UNLCK;
702 else if(numLock == 0) {
703 /* if no lock or unlock then nothing
704 to do since we do not know what it is */
705 FreeXid(xid);
706 return -EOPNOTSUPP;
707 }
708 rc = CIFSSMBPosixLock(xid, pTcon, netfid, 0 /* set */,
709 length, pfLock->fl_start,
710 posix_lock_type, wait_flag);
711 } else
712 rc = CIFSSMBLock(xid, pTcon, netfid, length, pfLock->fl_start,
713 numUnlock, numLock, lockType, wait_flag);
676 if (pfLock->fl_flags & FL_POSIX) 714 if (pfLock->fl_flags & FL_POSIX)
677 posix_lock_file_wait(file, pfLock); 715 posix_lock_file_wait(file, pfLock);
678 FreeXid(xid); 716 FreeXid(xid);
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 598eec9778f6..957ddd1571c6 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -565,11 +565,14 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
565 struct cifsInodeInfo *cifsInode; 565 struct cifsInodeInfo *cifsInode;
566 FILE_BASIC_INFO *pinfo_buf; 566 FILE_BASIC_INFO *pinfo_buf;
567 567
568 cFYI(1, ("cifs_unlink, inode = 0x%p with ", inode)); 568 cFYI(1, ("cifs_unlink, inode = 0x%p", inode));
569 569
570 xid = GetXid(); 570 xid = GetXid();
571 571
572 cifs_sb = CIFS_SB(inode->i_sb); 572 if(inode)
573 cifs_sb = CIFS_SB(inode->i_sb);
574 else
575 cifs_sb = CIFS_SB(direntry->d_sb);
573 pTcon = cifs_sb->tcon; 576 pTcon = cifs_sb->tcon;
574 577
575 /* Unlink can be called from rename so we can not grab the sem here 578 /* Unlink can be called from rename so we can not grab the sem here
@@ -609,9 +612,8 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
609 } 612 }
610 } else if (rc == -EACCES) { 613 } else if (rc == -EACCES) {
611 /* try only if r/o attribute set in local lookup data? */ 614 /* try only if r/o attribute set in local lookup data? */
612 pinfo_buf = kmalloc(sizeof(FILE_BASIC_INFO), GFP_KERNEL); 615 pinfo_buf = kzalloc(sizeof(FILE_BASIC_INFO), GFP_KERNEL);
613 if (pinfo_buf) { 616 if (pinfo_buf) {
614 memset(pinfo_buf, 0, sizeof(FILE_BASIC_INFO));
615 /* ATTRS set to normal clears r/o bit */ 617 /* ATTRS set to normal clears r/o bit */
616 pinfo_buf->Attributes = cpu_to_le32(ATTR_NORMAL); 618 pinfo_buf->Attributes = cpu_to_le32(ATTR_NORMAL);
617 if (!(pTcon->ses->flags & CIFS_SES_NT4)) 619 if (!(pTcon->ses->flags & CIFS_SES_NT4))
@@ -693,9 +695,11 @@ int cifs_unlink(struct inode *inode, struct dentry *direntry)
693 when needed */ 695 when needed */
694 direntry->d_inode->i_ctime = current_fs_time(inode->i_sb); 696 direntry->d_inode->i_ctime = current_fs_time(inode->i_sb);
695 } 697 }
696 inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb); 698 if(inode) {
697 cifsInode = CIFS_I(inode); 699 inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb);
698 cifsInode->time = 0; /* force revalidate of dir as well */ 700 cifsInode = CIFS_I(inode);
701 cifsInode->time = 0; /* force revalidate of dir as well */
702 }
699 703
700 kfree(full_path); 704 kfree(full_path);
701 FreeXid(xid); 705 FreeXid(xid);
@@ -1167,7 +1171,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1167 nfid, npid, FALSE); 1171 nfid, npid, FALSE);
1168 atomic_dec(&open_file->wrtPending); 1172 atomic_dec(&open_file->wrtPending);
1169 cFYI(1,("SetFSize for attrs rc = %d", rc)); 1173 cFYI(1,("SetFSize for attrs rc = %d", rc));
1170 if(rc == -EINVAL) { 1174 if((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1171 int bytes_written; 1175 int bytes_written;
1172 rc = CIFSSMBWrite(xid, pTcon, 1176 rc = CIFSSMBWrite(xid, pTcon,
1173 nfid, 0, attrs->ia_size, 1177 nfid, 0, attrs->ia_size,
@@ -1189,7 +1193,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1189 cifs_sb->mnt_cifs_flags & 1193 cifs_sb->mnt_cifs_flags &
1190 CIFS_MOUNT_MAP_SPECIAL_CHR); 1194 CIFS_MOUNT_MAP_SPECIAL_CHR);
1191 cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc)); 1195 cFYI(1, ("SetEOF by path (setattrs) rc = %d", rc));
1192 if(rc == -EINVAL) { 1196 if((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
1193 __u16 netfid; 1197 __u16 netfid;
1194 int oplock = FALSE; 1198 int oplock = FALSE;
1195 1199
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index 8d0da7c87c7b..9562f5bba65c 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -67,7 +67,7 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
67 cifs_sb_target->local_nls, 67 cifs_sb_target->local_nls,
68 cifs_sb_target->mnt_cifs_flags & 68 cifs_sb_target->mnt_cifs_flags &
69 CIFS_MOUNT_MAP_SPECIAL_CHR); 69 CIFS_MOUNT_MAP_SPECIAL_CHR);
70 if(rc == -EIO) 70 if((rc == -EIO) || (rc == -EINVAL))
71 rc = -EOPNOTSUPP; 71 rc = -EOPNOTSUPP;
72 } 72 }
73 73
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 432ba15e2c2d..fafd056426e4 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -72,10 +72,9 @@ sesInfoAlloc(void)
72 struct cifsSesInfo *ret_buf; 72 struct cifsSesInfo *ret_buf;
73 73
74 ret_buf = 74 ret_buf =
75 (struct cifsSesInfo *) kmalloc(sizeof (struct cifsSesInfo), 75 (struct cifsSesInfo *) kzalloc(sizeof (struct cifsSesInfo),
76 GFP_KERNEL); 76 GFP_KERNEL);
77 if (ret_buf) { 77 if (ret_buf) {
78 memset(ret_buf, 0, sizeof (struct cifsSesInfo));
79 write_lock(&GlobalSMBSeslock); 78 write_lock(&GlobalSMBSeslock);
80 atomic_inc(&sesInfoAllocCount); 79 atomic_inc(&sesInfoAllocCount);
81 ret_buf->status = CifsNew; 80 ret_buf->status = CifsNew;
@@ -110,10 +109,9 @@ tconInfoAlloc(void)
110{ 109{
111 struct cifsTconInfo *ret_buf; 110 struct cifsTconInfo *ret_buf;
112 ret_buf = 111 ret_buf =
113 (struct cifsTconInfo *) kmalloc(sizeof (struct cifsTconInfo), 112 (struct cifsTconInfo *) kzalloc(sizeof (struct cifsTconInfo),
114 GFP_KERNEL); 113 GFP_KERNEL);
115 if (ret_buf) { 114 if (ret_buf) {
116 memset(ret_buf, 0, sizeof (struct cifsTconInfo));
117 write_lock(&GlobalSMBSeslock); 115 write_lock(&GlobalSMBSeslock);
118 atomic_inc(&tconInfoAllocCount); 116 atomic_inc(&tconInfoAllocCount);
119 list_add(&ret_buf->cifsConnectionList, 117 list_add(&ret_buf->cifsConnectionList,
@@ -423,9 +421,7 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
423{ 421{
424 __u32 len = smb->smb_buf_length; 422 __u32 len = smb->smb_buf_length;
425 __u32 clc_len; /* calculated length */ 423 __u32 clc_len; /* calculated length */
426 cFYI(0, 424 cFYI(0, ("checkSMB Length: 0x%x, smb_buf_length: 0x%x", length, len));
427 ("Entering checkSMB with Length: %x, smb_buf_length: %x",
428 length, len));
429 if (((unsigned int)length < 2 + sizeof (struct smb_hdr)) || 425 if (((unsigned int)length < 2 + sizeof (struct smb_hdr)) ||
430 (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)) { 426 (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)) {
431 if ((unsigned int)length < 2 + sizeof (struct smb_hdr)) { 427 if ((unsigned int)length < 2 + sizeof (struct smb_hdr)) {
@@ -433,29 +429,36 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
433 sizeof (struct smb_hdr) - 1) 429 sizeof (struct smb_hdr) - 1)
434 && (smb->Status.CifsError != 0)) { 430 && (smb->Status.CifsError != 0)) {
435 smb->WordCount = 0; 431 smb->WordCount = 0;
436 return 0; /* some error cases do not return wct and bcc */ 432 /* some error cases do not return wct and bcc */
433 return 0;
437 } else { 434 } else {
438 cERROR(1, ("Length less than smb header size")); 435 cERROR(1, ("Length less than smb header size"));
439 } 436 }
440
441 } 437 }
442 if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) 438 if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4)
443 cERROR(1, 439 cERROR(1, ("smb length greater than MaxBufSize, mid=%d",
444 ("smb_buf_length greater than MaxBufSize")); 440 smb->Mid));
445 cERROR(1,
446 ("bad smb detected. Illegal length. mid=%d",
447 smb->Mid));
448 return 1; 441 return 1;
449 } 442 }
450 443
451 if (checkSMBhdr(smb, mid)) 444 if (checkSMBhdr(smb, mid))
452 return 1; 445 return 1;
453 clc_len = smbCalcSize_LE(smb); 446 clc_len = smbCalcSize_LE(smb);
454 if ((4 + len != clc_len) 447
455 || (4 + len != (unsigned int)length)) { 448 if(4 + len != (unsigned int)length) {
456 cERROR(1, ("Calculated size 0x%x vs actual length 0x%x", 449 cERROR(1, ("Length read does not match RFC1001 length %d",len));
457 clc_len, 4 + len)); 450 return 1;
458 cERROR(1, ("bad smb size detected for Mid=%d", smb->Mid)); 451 }
452
453 if (4 + len != clc_len) {
454 /* check if bcc wrapped around for large read responses */
455 if((len > 64 * 1024) && (len > clc_len)) {
456 /* check if lengths match mod 64K */
457 if(((4 + len) & 0xFFFF) == (clc_len & 0xFFFF))
458 return 0; /* bcc wrapped */
459 }
460 cFYI(1, ("Calculated size %d vs length %d mismatch for mid %d",
461 clc_len, 4 + len, smb->Mid));
459 /* Windows XP can return a few bytes too much, presumably 462 /* Windows XP can return a few bytes too much, presumably
460 an illegal pad, at the end of byte range lock responses 463 an illegal pad, at the end of byte range lock responses
461 so we allow for that three byte pad, as long as actual 464 so we allow for that three byte pad, as long as actual
@@ -469,8 +472,11 @@ checkSMB(struct smb_hdr *smb, __u16 mid, int length)
469 wct and bcc to minimum size and drop the t2 parms and data */ 472 wct and bcc to minimum size and drop the t2 parms and data */
470 if((4+len > clc_len) && (len <= clc_len + 512)) 473 if((4+len > clc_len) && (len <= clc_len + 512))
471 return 0; 474 return 0;
472 else 475 else {
476 cERROR(1, ("RFC1001 size %d bigger than SMB for Mid=%d",
477 len, smb->Mid));
473 return 1; 478 return 1;
479 }
474 } 480 }
475 return 0; 481 return 0;
476} 482}
diff --git a/fs/cifs/ntlmssp.c b/fs/cifs/ntlmssp.c
new file mode 100644
index 000000000000..78866f925747
--- /dev/null
+++ b/fs/cifs/ntlmssp.c
@@ -0,0 +1,129 @@
1/*
2 * fs/cifs/ntlmssp.h
3 *
4 * Copyright (c) International Business Machines Corp., 2006
5 * Author(s): Steve French (sfrench@us.ibm.com)
6 *
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 * the GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include "cifspdu.h"
23#include "cifsglob.h"
24#include "cifsproto.h"
25#include "cifs_unicode.h"
26#include "cifs_debug.h"
27#include "ntlmssp.h"
28#include "nterr.h"
29
30#ifdef CONFIG_CIFS_EXPERIMENTAL
31static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
32{
33 __u32 capabilities = 0;
34
35 /* init fields common to all four types of SessSetup */
36 /* note that header is initialized to zero in header_assemble */
37 pSMB->req.AndXCommand = 0xFF;
38 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
39 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
40
41 /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */
42
43 /* BB verify whether signing required on neg or just on auth frame
44 (and NTLM case) */
45
46 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
47 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
48
49 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
50 pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
51
52 if (ses->capabilities & CAP_UNICODE) {
53 pSMB->req.hdr.Flags2 |= SMBFLG2_UNICODE;
54 capabilities |= CAP_UNICODE;
55 }
56 if (ses->capabilities & CAP_STATUS32) {
57 pSMB->req.hdr.Flags2 |= SMBFLG2_ERR_STATUS;
58 capabilities |= CAP_STATUS32;
59 }
60 if (ses->capabilities & CAP_DFS) {
61 pSMB->req.hdr.Flags2 |= SMBFLG2_DFS;
62 capabilities |= CAP_DFS;
63 }
64
65 /* BB check whether to init vcnum BB */
66 return capabilities;
67}
68int
69CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, const int type,
70 int * pNTLMv2_flg, const struct nls_table *nls_cp)
71{
72 int rc = 0;
73 int wct;
74 struct smb_hdr *smb_buffer;
75 char *bcc_ptr;
76 SESSION_SETUP_ANDX *pSMB;
77 __u32 capabilities;
78
79 if(ses == NULL)
80 return -EINVAL;
81
82 cFYI(1,("SStp type: %d",type));
83 if(type < CIFS_NTLM) {
84#ifndef CONFIG_CIFS_WEAK_PW_HASH
85 /* LANMAN and plaintext are less secure and off by default.
86 So we make this explicitly be turned on in kconfig (in the
87 build) and turned on at runtime (changed from the default)
88 in proc/fs/cifs or via mount parm. Unfortunately this is
89 needed for old Win (e.g. Win95), some obscure NAS and OS/2 */
90 return -EOPNOTSUPP;
91#endif
92 wct = 10; /* lanman 2 style sessionsetup */
93 } else if(type < CIFS_NTLMSSP_NEG)
94 wct = 13; /* old style NTLM sessionsetup */
95 else /* same size for negotiate or auth, NTLMSSP or extended security */
96 wct = 12;
97
98 rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
99 (void **)&smb_buffer);
100 if(rc)
101 return rc;
102
103 pSMB = (SESSION_SETUP_ANDX *)smb_buffer;
104
105 capabilities = cifs_ssetup_hdr(ses, pSMB);
106 bcc_ptr = pByteArea(smb_buffer);
107 if(type > CIFS_NTLM) {
108 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
109 capabilities |= CAP_EXTENDED_SECURITY;
110 pSMB->req.Capabilities = cpu_to_le32(capabilities);
111 /* BB set password lengths */
112 } else if(type < CIFS_NTLM) /* lanman */ {
113 /* no capabilities flags in old lanman negotiation */
114 /* pSMB->old_req.PasswordLength = */ /* BB fixme BB */
115 } else /* type CIFS_NTLM */ {
116 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
117 pSMB->req_no_secext.CaseInsensitivePasswordLength =
118 cpu_to_le16(CIFS_SESSION_KEY_SIZE);
119 pSMB->req_no_secext.CaseSensitivePasswordLength =
120 cpu_to_le16(CIFS_SESSION_KEY_SIZE);
121 }
122
123
124/* rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buf_type, 0); */
125 /* SMB request buf freed in SendReceive2 */
126
127 return rc;
128}
129#endif /* CONFIG_CIFS_EXPERIMENTAL */
diff --git a/fs/cifs/ntlmssp.h b/fs/cifs/ntlmssp.h
index 803389b64a2c..d39b712a11c5 100644
--- a/fs/cifs/ntlmssp.h
+++ b/fs/cifs/ntlmssp.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * fs/cifs/ntlmssp.h 2 * fs/cifs/ntlmssp.h
3 * 3 *
4 * Copyright (c) International Business Machines Corp., 2002 4 * Copyright (c) International Business Machines Corp., 2002,2006
5 * Author(s): Steve French (sfrench@us.ibm.com) 5 * Author(s): Steve French (sfrench@us.ibm.com)
6 * 6 *
7 * This library is free software; you can redistribute it and/or modify 7 * This library is free software; you can redistribute it and/or modify
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 488bd0d81dcf..2f6e2825571e 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -604,7 +604,12 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
604 cifsFile->search_resume_name = NULL; 604 cifsFile->search_resume_name = NULL;
605 if(cifsFile->srch_inf.ntwrk_buf_start) { 605 if(cifsFile->srch_inf.ntwrk_buf_start) {
606 cFYI(1,("freeing SMB ff cache buf on search rewind")); 606 cFYI(1,("freeing SMB ff cache buf on search rewind"));
607 cifs_buf_release(cifsFile->srch_inf.ntwrk_buf_start); 607 if(cifsFile->srch_inf.smallBuf)
608 cifs_small_buf_release(cifsFile->srch_inf.
609 ntwrk_buf_start);
610 else
611 cifs_buf_release(cifsFile->srch_inf.
612 ntwrk_buf_start);
608 } 613 }
609 rc = initiate_cifs_search(xid,file); 614 rc = initiate_cifs_search(xid,file);
610 if(rc) { 615 if(rc) {
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index b12cb8a7da7c..3da80409466c 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -309,17 +309,16 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
309 309
310 *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */ 310 *pRespBufType = CIFS_NO_BUFFER; /* no response buf yet */
311 311
312 if (ses == NULL) { 312 if ((ses == NULL) || (ses->server == NULL)) {
313 cERROR(1,("Null smb session")); 313 cifs_small_buf_release(in_buf);
314 return -EIO; 314 cERROR(1,("Null session"));
315 }
316 if(ses->server == NULL) {
317 cERROR(1,("Null tcp session"));
318 return -EIO; 315 return -EIO;
319 } 316 }
320 317
321 if(ses->server->tcpStatus == CifsExiting) 318 if(ses->server->tcpStatus == CifsExiting) {
319 cifs_small_buf_release(in_buf);
322 return -ENOENT; 320 return -ENOENT;
321 }
323 322
324 /* Ensure that we do not send more than 50 overlapping requests 323 /* Ensure that we do not send more than 50 overlapping requests
325 to the same server. We may make this configurable later or 324 to the same server. We may make this configurable later or
@@ -346,6 +345,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
346 } else { 345 } else {
347 if(ses->server->tcpStatus == CifsExiting) { 346 if(ses->server->tcpStatus == CifsExiting) {
348 spin_unlock(&GlobalMid_Lock); 347 spin_unlock(&GlobalMid_Lock);
348 cifs_small_buf_release(in_buf);
349 return -ENOENT; 349 return -ENOENT;
350 } 350 }
351 351
@@ -385,6 +385,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
385 midQ = AllocMidQEntry(in_buf, ses); 385 midQ = AllocMidQEntry(in_buf, ses);
386 if (midQ == NULL) { 386 if (midQ == NULL) {
387 up(&ses->server->tcpSem); 387 up(&ses->server->tcpSem);
388 cifs_small_buf_release(in_buf);
388 /* If not lock req, update # of requests on wire to server */ 389 /* If not lock req, update # of requests on wire to server */
389 if(long_op < 3) { 390 if(long_op < 3) {
390 atomic_dec(&ses->server->inFlight); 391 atomic_dec(&ses->server->inFlight);
@@ -408,14 +409,18 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses,
408 if(rc < 0) { 409 if(rc < 0) {
409 DeleteMidQEntry(midQ); 410 DeleteMidQEntry(midQ);
410 up(&ses->server->tcpSem); 411 up(&ses->server->tcpSem);
412 cifs_small_buf_release(in_buf);
411 /* If not lock req, update # of requests on wire to server */ 413 /* If not lock req, update # of requests on wire to server */
412 if(long_op < 3) { 414 if(long_op < 3) {
413 atomic_dec(&ses->server->inFlight); 415 atomic_dec(&ses->server->inFlight);
414 wake_up(&ses->server->request_q); 416 wake_up(&ses->server->request_q);
415 } 417 }
416 return rc; 418 return rc;
417 } else 419 } else {
418 up(&ses->server->tcpSem); 420 up(&ses->server->tcpSem);
421 cifs_small_buf_release(in_buf);
422 }
423
419 if (long_op == -1) 424 if (long_op == -1)
420 goto cifs_no_response_exit2; 425 goto cifs_no_response_exit2;
421 else if (long_op == 2) /* writes past end of file can take loong time */ 426 else if (long_op == 2) /* writes past end of file can take loong time */
@@ -543,6 +548,7 @@ cifs_no_response_exit2:
543 548
544out_unlock2: 549out_unlock2:
545 up(&ses->server->tcpSem); 550 up(&ses->server->tcpSem);
551 cifs_small_buf_release(in_buf);
546 /* If not lock req, update # of requests on wire to server */ 552 /* If not lock req, update # of requests on wire to server */
547 if(long_op < 3) { 553 if(long_op < 3) {
548 atomic_dec(&ses->server->inFlight); 554 atomic_dec(&ses->server->inFlight);
diff --git a/fs/dcache.c b/fs/dcache.c
index 19458d399502..940d188e5d14 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1101,6 +1101,32 @@ next:
1101} 1101}
1102 1102
1103/** 1103/**
1104 * d_hash_and_lookup - hash the qstr then search for a dentry
1105 * @dir: Directory to search in
1106 * @name: qstr of name we wish to find
1107 *
1108 * On hash failure or on lookup failure NULL is returned.
1109 */
1110struct dentry *d_hash_and_lookup(struct dentry *dir, struct qstr *name)
1111{
1112 struct dentry *dentry = NULL;
1113
1114 /*
1115 * Check for a fs-specific hash function. Note that we must
1116 * calculate the standard hash first, as the d_op->d_hash()
1117 * routine may choose to leave the hash value unchanged.
1118 */
1119 name->hash = full_name_hash(name->name, name->len);
1120 if (dir->d_op && dir->d_op->d_hash) {
1121 if (dir->d_op->d_hash(dir, name) < 0)
1122 goto out;
1123 }
1124 dentry = d_lookup(dir, name);
1125out:
1126 return dentry;
1127}
1128
1129/**
1104 * d_validate - verify dentry provided from insecure source 1130 * d_validate - verify dentry provided from insecure source
1105 * @dentry: The dentry alleged to be valid child of @dparent 1131 * @dentry: The dentry alleged to be valid child of @dparent
1106 * @dparent: The parent dentry (known to be valid) 1132 * @dparent: The parent dentry (known to be valid)
@@ -1172,11 +1198,11 @@ void d_delete(struct dentry * dentry)
1172 spin_lock(&dentry->d_lock); 1198 spin_lock(&dentry->d_lock);
1173 isdir = S_ISDIR(dentry->d_inode->i_mode); 1199 isdir = S_ISDIR(dentry->d_inode->i_mode);
1174 if (atomic_read(&dentry->d_count) == 1) { 1200 if (atomic_read(&dentry->d_count) == 1) {
1175 /* remove this and other inotify debug checks after 2.6.18 */
1176 dentry->d_flags &= ~DCACHE_INOTIFY_PARENT_WATCHED;
1177
1178 dentry_iput(dentry); 1201 dentry_iput(dentry);
1179 fsnotify_nameremove(dentry, isdir); 1202 fsnotify_nameremove(dentry, isdir);
1203
1204 /* remove this and other inotify debug checks after 2.6.18 */
1205 dentry->d_flags &= ~DCACHE_INOTIFY_PARENT_WATCHED;
1180 return; 1206 return;
1181 } 1207 }
1182 1208
@@ -1616,26 +1642,12 @@ ino_t find_inode_number(struct dentry *dir, struct qstr *name)
1616 struct dentry * dentry; 1642 struct dentry * dentry;
1617 ino_t ino = 0; 1643 ino_t ino = 0;
1618 1644
1619 /* 1645 dentry = d_hash_and_lookup(dir, name);
1620 * Check for a fs-specific hash function. Note that we must 1646 if (dentry) {
1621 * calculate the standard hash first, as the d_op->d_hash()
1622 * routine may choose to leave the hash value unchanged.
1623 */
1624 name->hash = full_name_hash(name->name, name->len);
1625 if (dir->d_op && dir->d_op->d_hash)
1626 {
1627 if (dir->d_op->d_hash(dir, name) != 0)
1628 goto out;
1629 }
1630
1631 dentry = d_lookup(dir, name);
1632 if (dentry)
1633 {
1634 if (dentry->d_inode) 1647 if (dentry->d_inode)
1635 ino = dentry->d_inode->i_ino; 1648 ino = dentry->d_inode->i_ino;
1636 dput(dentry); 1649 dput(dentry);
1637 } 1650 }
1638out:
1639 return ino; 1651 return ino;
1640} 1652}
1641 1653
diff --git a/fs/direct-io.c b/fs/direct-io.c
index 910a8ed74b5d..b05d1b218776 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -929,8 +929,7 @@ do_holes:
929 block_in_page += this_chunk_blocks; 929 block_in_page += this_chunk_blocks;
930 dio->blocks_available -= this_chunk_blocks; 930 dio->blocks_available -= this_chunk_blocks;
931next_block: 931next_block:
932 if (dio->block_in_file > dio->final_block_in_request) 932 BUG_ON(dio->block_in_file > dio->final_block_in_request);
933 BUG();
934 if (dio->block_in_file == dio->final_block_in_request) 933 if (dio->block_in_file == dio->final_block_in_request)
935 break; 934 break;
936 } 935 }
diff --git a/fs/dquot.c b/fs/dquot.c
index 6b3886920939..81d87a413c68 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -590,8 +590,7 @@ we_slept:
590 atomic_dec(&dquot->dq_count); 590 atomic_dec(&dquot->dq_count);
591#ifdef __DQUOT_PARANOIA 591#ifdef __DQUOT_PARANOIA
592 /* sanity check */ 592 /* sanity check */
593 if (!list_empty(&dquot->dq_free)) 593 BUG_ON(!list_empty(&dquot->dq_free));
594 BUG();
595#endif 594#endif
596 put_dquot_last(dquot); 595 put_dquot_last(dquot);
597 spin_unlock(&dq_list_lock); 596 spin_unlock(&dq_list_lock);
@@ -666,8 +665,7 @@ we_slept:
666 return NODQUOT; 665 return NODQUOT;
667 } 666 }
668#ifdef __DQUOT_PARANOIA 667#ifdef __DQUOT_PARANOIA
669 if (!dquot->dq_sb) /* Has somebody invalidated entry under us? */ 668 BUG_ON(!dquot->dq_sb); /* Has somebody invalidated entry under us? */
670 BUG();
671#endif 669#endif
672 670
673 return dquot; 671 return dquot;
diff --git a/fs/exec.c b/fs/exec.c
index 950ebd43cdc3..0291a68a3626 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -561,7 +561,7 @@ static int exec_mmap(struct mm_struct *mm)
561 arch_pick_mmap_layout(mm); 561 arch_pick_mmap_layout(mm);
562 if (old_mm) { 562 if (old_mm) {
563 up_read(&old_mm->mmap_sem); 563 up_read(&old_mm->mmap_sem);
564 if (active_mm != old_mm) BUG(); 564 BUG_ON(active_mm != old_mm);
565 mmput(old_mm); 565 mmput(old_mm);
566 return 0; 566 return 0;
567 } 567 }
diff --git a/fs/fcntl.c b/fs/fcntl.c
index 2a2479196f96..d35cbc6bc112 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -453,8 +453,7 @@ static void send_sigio_to_task(struct task_struct *p,
453 /* Make sure we are called with one of the POLL_* 453 /* Make sure we are called with one of the POLL_*
454 reasons, otherwise we could leak kernel stack into 454 reasons, otherwise we could leak kernel stack into
455 userspace. */ 455 userspace. */
456 if ((reason & __SI_MASK) != __SI_POLL) 456 BUG_ON((reason & __SI_MASK) != __SI_POLL);
457 BUG();
458 if (reason - POLL_IN >= NSIGPOLL) 457 if (reason - POLL_IN >= NSIGPOLL)
459 si.si_band = ~0L; 458 si.si_band = ~0L;
460 else 459 else
diff --git a/fs/freevxfs/vxfs_olt.c b/fs/freevxfs/vxfs_olt.c
index 76a0708ae978..049500847903 100644
--- a/fs/freevxfs/vxfs_olt.c
+++ b/fs/freevxfs/vxfs_olt.c
@@ -42,24 +42,21 @@
42static inline void 42static inline void
43vxfs_get_fshead(struct vxfs_oltfshead *fshp, struct vxfs_sb_info *infp) 43vxfs_get_fshead(struct vxfs_oltfshead *fshp, struct vxfs_sb_info *infp)
44{ 44{
45 if (infp->vsi_fshino) 45 BUG_ON(infp->vsi_fshino);
46 BUG();
47 infp->vsi_fshino = fshp->olt_fsino[0]; 46 infp->vsi_fshino = fshp->olt_fsino[0];
48} 47}
49 48
50static inline void 49static inline void
51vxfs_get_ilist(struct vxfs_oltilist *ilistp, struct vxfs_sb_info *infp) 50vxfs_get_ilist(struct vxfs_oltilist *ilistp, struct vxfs_sb_info *infp)
52{ 51{
53 if (infp->vsi_iext) 52 BUG_ON(infp->vsi_iext);
54 BUG();
55 infp->vsi_iext = ilistp->olt_iext[0]; 53 infp->vsi_iext = ilistp->olt_iext[0];
56} 54}
57 55
58static inline u_long 56static inline u_long
59vxfs_oblock(struct super_block *sbp, daddr_t block, u_long bsize) 57vxfs_oblock(struct super_block *sbp, daddr_t block, u_long bsize)
60{ 58{
61 if (sbp->s_blocksize % bsize) 59 BUG_ON(sbp->s_blocksize % bsize);
62 BUG();
63 return (block * (sbp->s_blocksize / bsize)); 60 return (block * (sbp->s_blocksize / bsize));
64} 61}
65 62
diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c
index 8f07e8fbd03d..746abc9ecf70 100644
--- a/fs/hfsplus/bnode.c
+++ b/fs/hfsplus/bnode.c
@@ -466,8 +466,7 @@ void hfs_bnode_unhash(struct hfs_bnode *node)
466 for (p = &node->tree->node_hash[hfs_bnode_hash(node->this)]; 466 for (p = &node->tree->node_hash[hfs_bnode_hash(node->this)];
467 *p && *p != node; p = &(*p)->next_hash) 467 *p && *p != node; p = &(*p)->next_hash)
468 ; 468 ;
469 if (!*p) 469 BUG_ON(!*p);
470 BUG();
471 *p = node->next_hash; 470 *p = node->next_hash;
472 node->tree->node_hash_cnt--; 471 node->tree->node_hash_cnt--;
473} 472}
@@ -622,8 +621,7 @@ void hfs_bnode_put(struct hfs_bnode *node)
622 621
623 dprint(DBG_BNODE_REFS, "put_node(%d:%d): %d\n", 622 dprint(DBG_BNODE_REFS, "put_node(%d:%d): %d\n",
624 node->tree->cnid, node->this, atomic_read(&node->refcnt)); 623 node->tree->cnid, node->this, atomic_read(&node->refcnt));
625 if (!atomic_read(&node->refcnt)) 624 BUG_ON(!atomic_read(&node->refcnt));
626 BUG();
627 if (!atomic_dec_and_lock(&node->refcnt, &tree->hash_lock)) 625 if (!atomic_dec_and_lock(&node->refcnt, &tree->hash_lock))
628 return; 626 return;
629 for (i = 0; i < tree->pages_per_bnode; i++) { 627 for (i = 0; i < tree->pages_per_bnode; i++) {
diff --git a/fs/hfsplus/btree.c b/fs/hfsplus/btree.c
index a67edfa34e9e..effa8991999c 100644
--- a/fs/hfsplus/btree.c
+++ b/fs/hfsplus/btree.c
@@ -269,8 +269,7 @@ void hfs_bmap_free(struct hfs_bnode *node)
269 u8 *data, byte, m; 269 u8 *data, byte, m;
270 270
271 dprint(DBG_BNODE_MOD, "btree_free_node: %u\n", node->this); 271 dprint(DBG_BNODE_MOD, "btree_free_node: %u\n", node->this);
272 if (!node->this) 272 BUG_ON(!node->this);
273 BUG();
274 tree = node->tree; 273 tree = node->tree;
275 nidx = node->this; 274 nidx = node->this;
276 node = hfs_bnode_find(tree, 0); 275 node = hfs_bnode_find(tree, 0);
diff --git a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c
index 2ba20cdb5baa..5e6363be246f 100644
--- a/fs/hppfs/hppfs_kern.c
+++ b/fs/hppfs/hppfs_kern.c
@@ -216,10 +216,10 @@ static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry,
216static struct inode_operations hppfs_file_iops = { 216static struct inode_operations hppfs_file_iops = {
217}; 217};
218 218
219static ssize_t read_proc(struct file *file, char *buf, ssize_t count, 219static ssize_t read_proc(struct file *file, char __user *buf, ssize_t count,
220 loff_t *ppos, int is_user) 220 loff_t *ppos, int is_user)
221{ 221{
222 ssize_t (*read)(struct file *, char *, size_t, loff_t *); 222 ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
223 ssize_t n; 223 ssize_t n;
224 224
225 read = file->f_dentry->d_inode->i_fop->read; 225 read = file->f_dentry->d_inode->i_fop->read;
@@ -236,7 +236,7 @@ static ssize_t read_proc(struct file *file, char *buf, ssize_t count,
236 return n; 236 return n;
237} 237}
238 238
239static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count) 239static ssize_t hppfs_read_file(int fd, char __user *buf, ssize_t count)
240{ 240{
241 ssize_t n; 241 ssize_t n;
242 int cur, err; 242 int cur, err;
@@ -274,7 +274,7 @@ static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
274 return n; 274 return n;
275} 275}
276 276
277static ssize_t hppfs_read(struct file *file, char *buf, size_t count, 277static ssize_t hppfs_read(struct file *file, char __user *buf, size_t count,
278 loff_t *ppos) 278 loff_t *ppos)
279{ 279{
280 struct hppfs_private *hppfs = file->private_data; 280 struct hppfs_private *hppfs = file->private_data;
@@ -313,12 +313,12 @@ static ssize_t hppfs_read(struct file *file, char *buf, size_t count,
313 return(count); 313 return(count);
314} 314}
315 315
316static ssize_t hppfs_write(struct file *file, const char *buf, size_t len, 316static ssize_t hppfs_write(struct file *file, const char __user *buf, size_t len,
317 loff_t *ppos) 317 loff_t *ppos)
318{ 318{
319 struct hppfs_private *data = file->private_data; 319 struct hppfs_private *data = file->private_data;
320 struct file *proc_file = data->proc_file; 320 struct file *proc_file = data->proc_file;
321 ssize_t (*write)(struct file *, const char *, size_t, loff_t *); 321 ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
322 int err; 322 int err;
323 323
324 write = proc_file->f_dentry->d_inode->i_fop->write; 324 write = proc_file->f_dentry->d_inode->i_fop->write;
@@ -658,7 +658,7 @@ static struct super_operations hppfs_sbops = {
658 .statfs = hppfs_statfs, 658 .statfs = hppfs_statfs,
659}; 659};
660 660
661static int hppfs_readlink(struct dentry *dentry, char *buffer, int buflen) 661static int hppfs_readlink(struct dentry *dentry, char __user *buffer, int buflen)
662{ 662{
663 struct file *proc_file; 663 struct file *proc_file;
664 struct dentry *proc_dentry; 664 struct dentry *proc_dentry;
diff --git a/fs/inode.c b/fs/inode.c
index 32b7c3375021..3a2446a27d2c 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -172,8 +172,7 @@ static struct inode *alloc_inode(struct super_block *sb)
172 172
173void destroy_inode(struct inode *inode) 173void destroy_inode(struct inode *inode)
174{ 174{
175 if (inode_has_buffers(inode)) 175 BUG_ON(inode_has_buffers(inode));
176 BUG();
177 security_inode_free(inode); 176 security_inode_free(inode);
178 if (inode->i_sb->s_op->destroy_inode) 177 if (inode->i_sb->s_op->destroy_inode)
179 inode->i_sb->s_op->destroy_inode(inode); 178 inode->i_sb->s_op->destroy_inode(inode);
@@ -249,12 +248,9 @@ void clear_inode(struct inode *inode)
249 might_sleep(); 248 might_sleep();
250 invalidate_inode_buffers(inode); 249 invalidate_inode_buffers(inode);
251 250
252 if (inode->i_data.nrpages) 251 BUG_ON(inode->i_data.nrpages);
253 BUG(); 252 BUG_ON(!(inode->i_state & I_FREEING));
254 if (!(inode->i_state & I_FREEING)) 253 BUG_ON(inode->i_state & I_CLEAR);
255 BUG();
256 if (inode->i_state & I_CLEAR)
257 BUG();
258 wait_on_inode(inode); 254 wait_on_inode(inode);
259 DQUOT_DROP(inode); 255 DQUOT_DROP(inode);
260 if (inode->i_sb && inode->i_sb->s_op->clear_inode) 256 if (inode->i_sb && inode->i_sb->s_op->clear_inode)
@@ -1054,8 +1050,7 @@ void generic_delete_inode(struct inode *inode)
1054 hlist_del_init(&inode->i_hash); 1050 hlist_del_init(&inode->i_hash);
1055 spin_unlock(&inode_lock); 1051 spin_unlock(&inode_lock);
1056 wake_up_inode(inode); 1052 wake_up_inode(inode);
1057 if (inode->i_state != I_CLEAR) 1053 BUG_ON(inode->i_state != I_CLEAR);
1058 BUG();
1059 destroy_inode(inode); 1054 destroy_inode(inode);
1060} 1055}
1061 1056
diff --git a/fs/jffs2/background.c b/fs/jffs2/background.c
index 7b77a9541125..ff2a872e80e7 100644
--- a/fs/jffs2/background.c
+++ b/fs/jffs2/background.c
@@ -35,8 +35,7 @@ int jffs2_start_garbage_collect_thread(struct jffs2_sb_info *c)
35 pid_t pid; 35 pid_t pid;
36 int ret = 0; 36 int ret = 0;
37 37
38 if (c->gc_task) 38 BUG_ON(c->gc_task);
39 BUG();
40 39
41 init_completion(&c->gc_thread_start); 40 init_completion(&c->gc_thread_start);
42 init_completion(&c->gc_thread_exit); 41 init_completion(&c->gc_thread_exit);
diff --git a/fs/locks.c b/fs/locks.c
index 4d9e71d43e7e..dda83d6cd48b 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -168,18 +168,9 @@ static void locks_release_private(struct file_lock *fl)
168/* Free a lock which is not in use. */ 168/* Free a lock which is not in use. */
169static void locks_free_lock(struct file_lock *fl) 169static void locks_free_lock(struct file_lock *fl)
170{ 170{
171 if (fl == NULL) { 171 BUG_ON(waitqueue_active(&fl->fl_wait));
172 BUG(); 172 BUG_ON(!list_empty(&fl->fl_block));
173 return; 173 BUG_ON(!list_empty(&fl->fl_link));
174 }
175 if (waitqueue_active(&fl->fl_wait))
176 panic("Attempting to free lock with active wait queue");
177
178 if (!list_empty(&fl->fl_block))
179 panic("Attempting to free lock with active block list");
180
181 if (!list_empty(&fl->fl_link))
182 panic("Attempting to free lock on active lock list");
183 174
184 locks_release_private(fl); 175 locks_release_private(fl);
185 kmem_cache_free(filelock_cache, fl); 176 kmem_cache_free(filelock_cache, fl);
@@ -735,8 +726,9 @@ EXPORT_SYMBOL(posix_locks_deadlock);
735 * 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
736 * flock_lock_file and posix_lock_file. 727 * flock_lock_file and posix_lock_file.
737 */ 728 */
738static int flock_lock_file(struct file *filp, struct file_lock *new_fl) 729static int flock_lock_file(struct file *filp, struct file_lock *request)
739{ 730{
731 struct file_lock *new_fl = NULL;
740 struct file_lock **before; 732 struct file_lock **before;
741 struct inode * inode = filp->f_dentry->d_inode; 733 struct inode * inode = filp->f_dentry->d_inode;
742 int error = 0; 734 int error = 0;
@@ -751,17 +743,19 @@ static int flock_lock_file(struct file *filp, struct file_lock *new_fl)
751 continue; 743 continue;
752 if (filp != fl->fl_file) 744 if (filp != fl->fl_file)
753 continue; 745 continue;
754 if (new_fl->fl_type == fl->fl_type) 746 if (request->fl_type == fl->fl_type)
755 goto out; 747 goto out;
756 found = 1; 748 found = 1;
757 locks_delete_lock(before); 749 locks_delete_lock(before);
758 break; 750 break;
759 } 751 }
760 unlock_kernel();
761 752
762 if (new_fl->fl_type == F_UNLCK) 753 if (request->fl_type == F_UNLCK)
763 return 0; 754 goto out;
764 755
756 new_fl = locks_alloc_lock();
757 if (new_fl == NULL)
758 goto out;
765 /* 759 /*
766 * If a higher-priority process was blocked on the old file lock, 760 * If a higher-priority process was blocked on the old file lock,
767 * give it the opportunity to lock the file. 761 * give it the opportunity to lock the file.
@@ -769,26 +763,27 @@ static int flock_lock_file(struct file *filp, struct file_lock *new_fl)
769 if (found) 763 if (found)
770 cond_resched(); 764 cond_resched();
771 765
772 lock_kernel();
773 for_each_lock(inode, before) { 766 for_each_lock(inode, before) {
774 struct file_lock *fl = *before; 767 struct file_lock *fl = *before;
775 if (IS_POSIX(fl)) 768 if (IS_POSIX(fl))
776 break; 769 break;
777 if (IS_LEASE(fl)) 770 if (IS_LEASE(fl))
778 continue; 771 continue;
779 if (!flock_locks_conflict(new_fl, fl)) 772 if (!flock_locks_conflict(request, fl))
780 continue; 773 continue;
781 error = -EAGAIN; 774 error = -EAGAIN;
782 if (new_fl->fl_flags & FL_SLEEP) { 775 if (request->fl_flags & FL_SLEEP)
783 locks_insert_block(fl, new_fl); 776 locks_insert_block(fl, request);
784 }
785 goto out; 777 goto out;
786 } 778 }
779 locks_copy_lock(new_fl, request);
787 locks_insert_lock(&inode->i_flock, new_fl); 780 locks_insert_lock(&inode->i_flock, new_fl);
788 error = 0; 781 new_fl = NULL;
789 782
790out: 783out:
791 unlock_kernel(); 784 unlock_kernel();
785 if (new_fl)
786 locks_free_lock(new_fl);
792 return error; 787 return error;
793} 788}
794 789
@@ -1569,9 +1564,7 @@ asmlinkage long sys_flock(unsigned int fd, unsigned int cmd)
1569 error = flock_lock_file_wait(filp, lock); 1564 error = flock_lock_file_wait(filp, lock);
1570 1565
1571 out_free: 1566 out_free:
1572 if (list_empty(&lock->fl_link)) { 1567 locks_free_lock(lock);
1573 locks_free_lock(lock);
1574 }
1575 1568
1576 out_putf: 1569 out_putf:
1577 fput(filp); 1570 fput(filp);
diff --git a/fs/msdos/namei.c b/fs/msdos/namei.c
index 626a367bcd81..5b76ccd19e3f 100644
--- a/fs/msdos/namei.c
+++ b/fs/msdos/namei.c
@@ -12,14 +12,6 @@
12#include <linux/msdos_fs.h> 12#include <linux/msdos_fs.h>
13#include <linux/smp_lock.h> 13#include <linux/smp_lock.h>
14 14
15/* MS-DOS "device special files" */
16static const unsigned char *reserved_names[] = {
17 "CON ", "PRN ", "NUL ", "AUX ",
18 "LPT1 ", "LPT2 ", "LPT3 ", "LPT4 ",
19 "COM1 ", "COM2 ", "COM3 ", "COM4 ",
20 NULL
21};
22
23/* Characters that are undesirable in an MS-DOS file name */ 15/* Characters that are undesirable in an MS-DOS file name */
24static unsigned char bad_chars[] = "*?<>|\""; 16static unsigned char bad_chars[] = "*?<>|\"";
25static unsigned char bad_if_strict_pc[] = "+=,; "; 17static unsigned char bad_if_strict_pc[] = "+=,; ";
@@ -40,7 +32,6 @@ static int msdos_format_name(const unsigned char *name, int len,
40 */ 32 */
41{ 33{
42 unsigned char *walk; 34 unsigned char *walk;
43 const unsigned char **reserved;
44 unsigned char c; 35 unsigned char c;
45 int space; 36 int space;
46 37
@@ -127,11 +118,7 @@ static int msdos_format_name(const unsigned char *name, int len,
127 } 118 }
128 while (walk - res < MSDOS_NAME) 119 while (walk - res < MSDOS_NAME)
129 *walk++ = ' '; 120 *walk++ = ' ';
130 if (!opts->atari) 121
131 /* GEMDOS is less stupid and has no reserved names */
132 for (reserved = reserved_names; *reserved; reserved++)
133 if (!strncmp(res, *reserved, 8))
134 return -EINVAL;
135 return 0; 122 return 0;
136} 123}
137 124
diff --git a/fs/namei.c b/fs/namei.c
index 22f6e8d16aa8..96723ae83c89 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1254,7 +1254,7 @@ out:
1254 return dentry; 1254 return dentry;
1255} 1255}
1256 1256
1257struct dentry * lookup_hash(struct nameidata *nd) 1257static struct dentry *lookup_hash(struct nameidata *nd)
1258{ 1258{
1259 return __lookup_hash(&nd->last, nd->dentry, nd); 1259 return __lookup_hash(&nd->last, nd->dentry, nd);
1260} 1260}
@@ -2697,7 +2697,6 @@ EXPORT_SYMBOL(follow_up);
2697EXPORT_SYMBOL(get_write_access); /* binfmt_aout */ 2697EXPORT_SYMBOL(get_write_access); /* binfmt_aout */
2698EXPORT_SYMBOL(getname); 2698EXPORT_SYMBOL(getname);
2699EXPORT_SYMBOL(lock_rename); 2699EXPORT_SYMBOL(lock_rename);
2700EXPORT_SYMBOL(lookup_hash);
2701EXPORT_SYMBOL(lookup_one_len); 2700EXPORT_SYMBOL(lookup_one_len);
2702EXPORT_SYMBOL(page_follow_link_light); 2701EXPORT_SYMBOL(page_follow_link_light);
2703EXPORT_SYMBOL(page_put_link); 2702EXPORT_SYMBOL(page_put_link);
diff --git a/fs/pipe.c b/fs/pipe.c
index 109a102c150d..795df987cd38 100644
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -95,6 +95,8 @@ static void anon_pipe_buf_release(struct pipe_inode_info *info, struct pipe_buff
95{ 95{
96 struct page *page = buf->page; 96 struct page *page = buf->page;
97 97
98 buf->flags &= ~PIPE_BUF_FLAG_STOLEN;
99
98 /* 100 /*
99 * If nobody else uses this page, and we don't already have a 101 * If nobody else uses this page, and we don't already have a
100 * temporary page, let's keep track of it as a one-deep 102 * temporary page, let's keep track of it as a one-deep
@@ -124,7 +126,7 @@ static void anon_pipe_buf_unmap(struct pipe_inode_info *info, struct pipe_buffer
124static int anon_pipe_buf_steal(struct pipe_inode_info *info, 126static int anon_pipe_buf_steal(struct pipe_inode_info *info,
125 struct pipe_buffer *buf) 127 struct pipe_buffer *buf)
126{ 128{
127 buf->stolen = 1; 129 buf->flags |= PIPE_BUF_FLAG_STOLEN;
128 return 0; 130 return 0;
129} 131}
130 132
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 8f1f49ceebec..a3a3eecef689 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -534,12 +534,15 @@ static int proc_oom_score(struct task_struct *task, char *buffer)
534 534
535/* If the process being read is separated by chroot from the reading process, 535/* If the process being read is separated by chroot from the reading process,
536 * don't let the reader access the threads. 536 * don't let the reader access the threads.
537 *
538 * note: this does dput(root) and mntput(vfsmnt) on exit.
537 */ 539 */
538static int proc_check_chroot(struct dentry *root, struct vfsmount *vfsmnt) 540static int proc_check_chroot(struct dentry *root, struct vfsmount *vfsmnt)
539{ 541{
540 struct dentry *de, *base; 542 struct dentry *de, *base;
541 struct vfsmount *our_vfsmnt, *mnt; 543 struct vfsmount *our_vfsmnt, *mnt;
542 int res = 0; 544 int res = 0;
545
543 read_lock(&current->fs->lock); 546 read_lock(&current->fs->lock);
544 our_vfsmnt = mntget(current->fs->rootmnt); 547 our_vfsmnt = mntget(current->fs->rootmnt);
545 base = dget(current->fs->root); 548 base = dget(current->fs->root);
@@ -549,11 +552,11 @@ static int proc_check_chroot(struct dentry *root, struct vfsmount *vfsmnt)
549 de = root; 552 de = root;
550 mnt = vfsmnt; 553 mnt = vfsmnt;
551 554
552 while (vfsmnt != our_vfsmnt) { 555 while (mnt != our_vfsmnt) {
553 if (vfsmnt == vfsmnt->mnt_parent) 556 if (mnt == mnt->mnt_parent)
554 goto out; 557 goto out;
555 de = vfsmnt->mnt_mountpoint; 558 de = mnt->mnt_mountpoint;
556 vfsmnt = vfsmnt->mnt_parent; 559 mnt = mnt->mnt_parent;
557 } 560 }
558 561
559 if (!is_subdir(de, base)) 562 if (!is_subdir(de, base))
@@ -564,7 +567,7 @@ exit:
564 dput(base); 567 dput(base);
565 mntput(our_vfsmnt); 568 mntput(our_vfsmnt);
566 dput(root); 569 dput(root);
567 mntput(mnt); 570 mntput(vfsmnt);
568 return res; 571 return res;
569out: 572out:
570 spin_unlock(&vfsmount_lock); 573 spin_unlock(&vfsmount_lock);
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index ef5a3323f4b5..5c10ea157425 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -249,144 +249,60 @@ static int cpuinfo_open(struct inode *inode, struct file *file)
249 return seq_open(file, &cpuinfo_op); 249 return seq_open(file, &cpuinfo_op);
250} 250}
251 251
252enum devinfo_states { 252static struct file_operations proc_cpuinfo_operations = {
253 CHR_HDR, 253 .open = cpuinfo_open,
254 CHR_LIST, 254 .read = seq_read,
255 BLK_HDR, 255 .llseek = seq_lseek,
256 BLK_LIST, 256 .release = seq_release,
257 DEVINFO_DONE
258};
259
260struct devinfo_state {
261 void *chrdev;
262 void *blkdev;
263 unsigned int num_records;
264 unsigned int cur_record;
265 enum devinfo_states state;
266}; 257};
267 258
268static void *devinfo_start(struct seq_file *f, loff_t *pos) 259static int devinfo_show(struct seq_file *f, void *v)
269{ 260{
270 struct devinfo_state *info = f->private; 261 int i = *(loff_t *) v;
271 262
272 if (*pos) { 263 if (i < CHRDEV_MAJOR_HASH_SIZE) {
273 if ((info) && (*pos <= info->num_records)) 264 if (i == 0)
274 return info; 265 seq_printf(f, "Character devices:\n");
275 return NULL; 266 chrdev_show(f, i);
267 } else {
268 i -= CHRDEV_MAJOR_HASH_SIZE;
269 if (i == 0)
270 seq_printf(f, "\nBlock devices:\n");
271 blkdev_show(f, i);
276 } 272 }
277 info = kmalloc(sizeof(*info), GFP_KERNEL); 273 return 0;
278 f->private = info;
279 info->chrdev = acquire_chrdev_list();
280 info->blkdev = acquire_blkdev_list();
281 info->state = CHR_HDR;
282 info->num_records = count_chrdev_list();
283 info->num_records += count_blkdev_list();
284 info->num_records += 2; /* Character and Block headers */
285 *pos = 1;
286 info->cur_record = *pos;
287 return info;
288} 274}
289 275
290static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos) 276static void *devinfo_start(struct seq_file *f, loff_t *pos)
291{ 277{
292 int idummy; 278 if (*pos < (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
293 char *ndummy; 279 return pos;
294 struct devinfo_state *info = f->private; 280 return NULL;
295
296 switch (info->state) {
297 case CHR_HDR:
298 info->state = CHR_LIST;
299 (*pos)++;
300 /*fallthrough*/
301 case CHR_LIST:
302 if (get_chrdev_info(info->chrdev,&idummy,&ndummy)) {
303 /*
304 * The character dev list is complete
305 */
306 info->state = BLK_HDR;
307 } else {
308 info->chrdev = get_next_chrdev(info->chrdev);
309 }
310 (*pos)++;
311 break;
312 case BLK_HDR:
313 info->state = BLK_LIST;
314 (*pos)++;
315 /*fallthrough*/
316 case BLK_LIST:
317 if (get_blkdev_info(info->blkdev,&idummy,&ndummy)) {
318 /*
319 * The block dev list is complete
320 */
321 info->state = DEVINFO_DONE;
322 } else {
323 info->blkdev = get_next_blkdev(info->blkdev);
324 }
325 (*pos)++;
326 break;
327 case DEVINFO_DONE:
328 (*pos)++;
329 info->cur_record = *pos;
330 info = NULL;
331 break;
332 default:
333 break;
334 }
335 if (info)
336 info->cur_record = *pos;
337 return info;
338} 281}
339 282
340static void devinfo_stop(struct seq_file *f, void *v) 283static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos)
341{ 284{
342 struct devinfo_state *info = f->private; 285 (*pos)++;
343 286 if (*pos >= (BLKDEV_MAJOR_HASH_SIZE + CHRDEV_MAJOR_HASH_SIZE))
344 if (info) { 287 return NULL;
345 release_chrdev_list(info->chrdev); 288 return pos;
346 release_blkdev_list(info->blkdev);
347 f->private = NULL;
348 kfree(info);
349 }
350} 289}
351 290
352static int devinfo_show(struct seq_file *f, void *arg) 291static void devinfo_stop(struct seq_file *f, void *v)
353{ 292{
354 int major; 293 /* Nothing to do */
355 char *name;
356 struct devinfo_state *info = f->private;
357
358 switch(info->state) {
359 case CHR_HDR:
360 seq_printf(f,"Character devices:\n");
361 /* fallthrough */
362 case CHR_LIST:
363 if (!get_chrdev_info(info->chrdev,&major,&name))
364 seq_printf(f,"%3d %s\n",major,name);
365 break;
366 case BLK_HDR:
367 seq_printf(f,"\nBlock devices:\n");
368 /* fallthrough */
369 case BLK_LIST:
370 if (!get_blkdev_info(info->blkdev,&major,&name))
371 seq_printf(f,"%3d %s\n",major,name);
372 break;
373 default:
374 break;
375 }
376
377 return 0;
378} 294}
379 295
380static struct seq_operations devinfo_op = { 296static struct seq_operations devinfo_ops = {
381 .start = devinfo_start, 297 .start = devinfo_start,
382 .next = devinfo_next, 298 .next = devinfo_next,
383 .stop = devinfo_stop, 299 .stop = devinfo_stop,
384 .show = devinfo_show, 300 .show = devinfo_show
385}; 301};
386 302
387static int devinfo_open(struct inode *inode, struct file *file) 303static int devinfo_open(struct inode *inode, struct file *filp)
388{ 304{
389 return seq_open(file, &devinfo_op); 305 return seq_open(filp, &devinfo_ops);
390} 306}
391 307
392static struct file_operations proc_devinfo_operations = { 308static struct file_operations proc_devinfo_operations = {
@@ -396,13 +312,6 @@ static struct file_operations proc_devinfo_operations = {
396 .release = seq_release, 312 .release = seq_release,
397}; 313};
398 314
399static struct file_operations proc_cpuinfo_operations = {
400 .open = cpuinfo_open,
401 .read = seq_read,
402 .llseek = seq_lseek,
403 .release = seq_release,
404};
405
406extern struct seq_operations vmstat_op; 315extern struct seq_operations vmstat_op;
407static int vmstat_open(struct inode *inode, struct file *file) 316static int vmstat_open(struct inode *inode, struct file *file)
408{ 317{
diff --git a/fs/select.c b/fs/select.c
index b3a3a1326af6..071660fa7b01 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -314,7 +314,7 @@ static int core_sys_select(int n, fd_set __user *inp, fd_set __user *outp,
314 int ret, size, max_fdset; 314 int ret, size, max_fdset;
315 struct fdtable *fdt; 315 struct fdtable *fdt;
316 /* Allocate small arguments on the stack to save memory and be faster */ 316 /* Allocate small arguments on the stack to save memory and be faster */
317 char stack_fds[SELECT_STACK_ALLOC]; 317 long stack_fds[SELECT_STACK_ALLOC/sizeof(long)];
318 318
319 ret = -EINVAL; 319 ret = -EINVAL;
320 if (n < 0) 320 if (n < 0)
@@ -639,8 +639,10 @@ int do_sys_poll(struct pollfd __user *ufds, unsigned int nfds, s64 *timeout)
639 struct poll_list *walk; 639 struct poll_list *walk;
640 struct fdtable *fdt; 640 struct fdtable *fdt;
641 int max_fdset; 641 int max_fdset;
642 /* Allocate small arguments on the stack to save memory and be faster */ 642 /* Allocate small arguments on the stack to save memory and be
643 char stack_pps[POLL_STACK_ALLOC]; 643 faster - use long to make sure the buffer is aligned properly
644 on 64 bit archs to avoid unaligned access */
645 long stack_pps[POLL_STACK_ALLOC/sizeof(long)];
644 struct poll_list *stack_pp = NULL; 646 struct poll_list *stack_pp = NULL;
645 647
646 /* Do a sanity check on nfds ... */ 648 /* Do a sanity check on nfds ... */
diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c
index c56bd99a9701..ed9a24d19d7d 100644
--- a/fs/smbfs/file.c
+++ b/fs/smbfs/file.c
@@ -178,11 +178,9 @@ smb_writepage(struct page *page, struct writeback_control *wbc)
178 unsigned offset = PAGE_CACHE_SIZE; 178 unsigned offset = PAGE_CACHE_SIZE;
179 int err; 179 int err;
180 180
181 if (!mapping) 181 BUG_ON(!mapping);
182 BUG();
183 inode = mapping->host; 182 inode = mapping->host;
184 if (!inode) 183 BUG_ON(!inode);
185 BUG();
186 184
187 end_index = inode->i_size >> PAGE_CACHE_SHIFT; 185 end_index = inode->i_size >> PAGE_CACHE_SHIFT;
188 186
diff --git a/fs/splice.c b/fs/splice.c
index 7c2bbf18d7a7..bfa42a277bb8 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -22,7 +22,10 @@
22#include <linux/pipe_fs_i.h> 22#include <linux/pipe_fs_i.h>
23#include <linux/mm_inline.h> 23#include <linux/mm_inline.h>
24#include <linux/swap.h> 24#include <linux/swap.h>
25#include <linux/writeback.h>
26#include <linux/buffer_head.h>
25#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/syscalls.h>
26 29
27/* 30/*
28 * Passed to the actors 31 * Passed to the actors
@@ -34,28 +37,37 @@ struct splice_desc {
34 loff_t pos; /* file position */ 37 loff_t pos; /* file position */
35}; 38};
36 39
40/*
41 * Attempt to steal a page from a pipe buffer. This should perhaps go into
42 * a vm helper function, it's already simplified quite a bit by the
43 * addition of remove_mapping(). If success is returned, the caller may
44 * attempt to reuse this page for another destination.
45 */
37static int page_cache_pipe_buf_steal(struct pipe_inode_info *info, 46static int page_cache_pipe_buf_steal(struct pipe_inode_info *info,
38 struct pipe_buffer *buf) 47 struct pipe_buffer *buf)
39{ 48{
40 struct page *page = buf->page; 49 struct page *page = buf->page;
50 struct address_space *mapping = page_mapping(page);
41 51
42 WARN_ON(!PageLocked(page)); 52 WARN_ON(!PageLocked(page));
43 WARN_ON(!PageUptodate(page)); 53 WARN_ON(!PageUptodate(page));
44 54
45 if (!remove_mapping(page_mapping(page), page)) 55 /*
46 return 1; 56 * At least for ext2 with nobh option, we need to wait on writeback
57 * completing on this page, since we'll remove it from the pagecache.
58 * Otherwise truncate wont wait on the page, allowing the disk
59 * blocks to be reused by someone else before we actually wrote our
60 * data to them. fs corruption ensues.
61 */
62 wait_on_page_writeback(page);
47 63
48 if (PageLRU(page)) { 64 if (PagePrivate(page))
49 struct zone *zone = page_zone(page); 65 try_to_release_page(page, mapping_gfp_mask(mapping));
50 66
51 spin_lock_irq(&zone->lru_lock); 67 if (!remove_mapping(mapping, page))
52 BUG_ON(!PageLRU(page)); 68 return 1;
53 __ClearPageLRU(page);
54 del_page_from_lru(zone, page);
55 spin_unlock_irq(&zone->lru_lock);
56 }
57 69
58 buf->stolen = 1; 70 buf->flags |= PIPE_BUF_FLAG_STOLEN | PIPE_BUF_FLAG_LRU;
59 return 0; 71 return 0;
60} 72}
61 73
@@ -64,7 +76,7 @@ static void page_cache_pipe_buf_release(struct pipe_inode_info *info,
64{ 76{
65 page_cache_release(buf->page); 77 page_cache_release(buf->page);
66 buf->page = NULL; 78 buf->page = NULL;
67 buf->stolen = 0; 79 buf->flags &= ~(PIPE_BUF_FLAG_STOLEN | PIPE_BUF_FLAG_LRU);
68} 80}
69 81
70static void *page_cache_pipe_buf_map(struct file *file, 82static void *page_cache_pipe_buf_map(struct file *file,
@@ -91,8 +103,7 @@ static void *page_cache_pipe_buf_map(struct file *file,
91static void page_cache_pipe_buf_unmap(struct pipe_inode_info *info, 103static void page_cache_pipe_buf_unmap(struct pipe_inode_info *info,
92 struct pipe_buffer *buf) 104 struct pipe_buffer *buf)
93{ 105{
94 if (!buf->stolen) 106 unlock_page(buf->page);
95 unlock_page(buf->page);
96 kunmap(buf->page); 107 kunmap(buf->page);
97} 108}
98 109
@@ -104,9 +115,13 @@ static struct pipe_buf_operations page_cache_pipe_buf_ops = {
104 .steal = page_cache_pipe_buf_steal, 115 .steal = page_cache_pipe_buf_steal,
105}; 116};
106 117
118/*
119 * Pipe output worker. This sets up our pipe format with the page cache
120 * pipe buffer operations. Otherwise very similar to the regular pipe_writev().
121 */
107static ssize_t move_to_pipe(struct inode *inode, struct page **pages, 122static ssize_t move_to_pipe(struct inode *inode, struct page **pages,
108 int nr_pages, unsigned long offset, 123 int nr_pages, unsigned long offset,
109 unsigned long len) 124 unsigned long len, unsigned int flags)
110{ 125{
111 struct pipe_inode_info *info; 126 struct pipe_inode_info *info;
112 int ret, do_wakeup, i; 127 int ret, do_wakeup, i;
@@ -159,6 +174,12 @@ static ssize_t move_to_pipe(struct inode *inode, struct page **pages,
159 break; 174 break;
160 } 175 }
161 176
177 if (flags & SPLICE_F_NONBLOCK) {
178 if (!ret)
179 ret = -EAGAIN;
180 break;
181 }
182
162 if (signal_pending(current)) { 183 if (signal_pending(current)) {
163 if (!ret) 184 if (!ret)
164 ret = -ERESTARTSYS; 185 ret = -ERESTARTSYS;
@@ -191,7 +212,7 @@ static ssize_t move_to_pipe(struct inode *inode, struct page **pages,
191} 212}
192 213
193static int __generic_file_splice_read(struct file *in, struct inode *pipe, 214static int __generic_file_splice_read(struct file *in, struct inode *pipe,
194 size_t len) 215 size_t len, unsigned int flags)
195{ 216{
196 struct address_space *mapping = in->f_mapping; 217 struct address_space *mapping = in->f_mapping;
197 unsigned int offset, nr_pages; 218 unsigned int offset, nr_pages;
@@ -231,9 +252,9 @@ static int __generic_file_splice_read(struct file *in, struct inode *pipe,
231 * fill shadow[] with pages at the right locations, so we only 252 * fill shadow[] with pages at the right locations, so we only
232 * have to fill holes 253 * have to fill holes
233 */ 254 */
234 memset(shadow, 0, i * sizeof(struct page *)); 255 memset(shadow, 0, nr_pages * sizeof(struct page *));
235 for (j = 0, pidx = index; j < i; pidx++, j++) 256 for (j = 0; j < i; j++)
236 shadow[pages[j]->index - pidx] = pages[j]; 257 shadow[pages[j]->index - index] = pages[j];
237 258
238 /* 259 /*
239 * now fill in the holes 260 * now fill in the holes
@@ -279,9 +300,19 @@ static int __generic_file_splice_read(struct file *in, struct inode *pipe,
279 * Now we splice them into the pipe.. 300 * Now we splice them into the pipe..
280 */ 301 */
281splice_them: 302splice_them:
282 return move_to_pipe(pipe, pages, i, offset, len); 303 return move_to_pipe(pipe, pages, i, offset, len, flags);
283} 304}
284 305
306/**
307 * generic_file_splice_read - splice data from file to a pipe
308 * @in: file to splice from
309 * @pipe: pipe to splice to
310 * @len: number of bytes to splice
311 * @flags: splice modifier flags
312 *
313 * Will read pages from given file and fill them into a pipe.
314 *
315 */
285ssize_t generic_file_splice_read(struct file *in, struct inode *pipe, 316ssize_t generic_file_splice_read(struct file *in, struct inode *pipe,
286 size_t len, unsigned int flags) 317 size_t len, unsigned int flags)
287{ 318{
@@ -291,7 +322,7 @@ ssize_t generic_file_splice_read(struct file *in, struct inode *pipe,
291 ret = 0; 322 ret = 0;
292 spliced = 0; 323 spliced = 0;
293 while (len) { 324 while (len) {
294 ret = __generic_file_splice_read(in, pipe, len); 325 ret = __generic_file_splice_read(in, pipe, len, flags);
295 326
296 if (ret <= 0) 327 if (ret <= 0)
297 break; 328 break;
@@ -299,6 +330,11 @@ ssize_t generic_file_splice_read(struct file *in, struct inode *pipe,
299 in->f_pos += ret; 330 in->f_pos += ret;
300 len -= ret; 331 len -= ret;
301 spliced += ret; 332 spliced += ret;
333
334 if (!(flags & SPLICE_F_NONBLOCK))
335 continue;
336 ret = -EAGAIN;
337 break;
302 } 338 }
303 339
304 if (spliced) 340 if (spliced)
@@ -307,8 +343,11 @@ ssize_t generic_file_splice_read(struct file *in, struct inode *pipe,
307 return ret; 343 return ret;
308} 344}
309 345
346EXPORT_SYMBOL(generic_file_splice_read);
347
310/* 348/*
311 * Send 'len' bytes to socket from 'file' at position 'pos' using sendpage(). 349 * Send 'sd->len' bytes to socket from 'sd->file' at position 'sd->pos'
350 * using sendpage().
312 */ 351 */
313static int pipe_to_sendpage(struct pipe_inode_info *info, 352static int pipe_to_sendpage(struct pipe_inode_info *info,
314 struct pipe_buffer *buf, struct splice_desc *sd) 353 struct pipe_buffer *buf, struct splice_desc *sd)
@@ -318,6 +357,7 @@ static int pipe_to_sendpage(struct pipe_inode_info *info,
318 unsigned int offset; 357 unsigned int offset;
319 ssize_t ret; 358 ssize_t ret;
320 void *ptr; 359 void *ptr;
360 int more;
321 361
322 /* 362 /*
323 * sub-optimal, but we are limited by the pipe ->map. we don't 363 * sub-optimal, but we are limited by the pipe ->map. we don't
@@ -330,9 +370,9 @@ static int pipe_to_sendpage(struct pipe_inode_info *info,
330 return PTR_ERR(ptr); 370 return PTR_ERR(ptr);
331 371
332 offset = pos & ~PAGE_CACHE_MASK; 372 offset = pos & ~PAGE_CACHE_MASK;
373 more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len;
333 374
334 ret = file->f_op->sendpage(file, buf->page, offset, sd->len, &pos, 375 ret = file->f_op->sendpage(file, buf->page, offset, sd->len, &pos,more);
335 sd->len < sd->total_len);
336 376
337 buf->ops->unmap(info, buf); 377 buf->ops->unmap(info, buf);
338 if (ret == sd->len) 378 if (ret == sd->len)
@@ -354,16 +394,19 @@ static int pipe_to_sendpage(struct pipe_inode_info *info,
354 * - Destination page does not exist, we can add the pipe page to 394 * - Destination page does not exist, we can add the pipe page to
355 * the page cache and avoid the copy. 395 * the page cache and avoid the copy.
356 * 396 *
357 * For now we just do the slower thing and always copy pages over, it's 397 * If asked to move pages to the output file (SPLICE_F_MOVE is set in
358 * easier than migrating pages from the pipe to the target file. For the 398 * sd->flags), we attempt to migrate pages from the pipe to the output
359 * case of doing file | file splicing, the migrate approach had some LRU 399 * file address space page cache. This is possible if no one else has
360 * nastiness... 400 * the pipe page referenced outside of the pipe and page cache. If
401 * SPLICE_F_MOVE isn't set, or we cannot move the page, we simply create
402 * a new page in the output file page cache and fill/dirty that.
361 */ 403 */
362static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf, 404static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf,
363 struct splice_desc *sd) 405 struct splice_desc *sd)
364{ 406{
365 struct file *file = sd->file; 407 struct file *file = sd->file;
366 struct address_space *mapping = file->f_mapping; 408 struct address_space *mapping = file->f_mapping;
409 gfp_t gfp_mask = mapping_gfp_mask(mapping);
367 unsigned int offset; 410 unsigned int offset;
368 struct page *page; 411 struct page *page;
369 pgoff_t index; 412 pgoff_t index;
@@ -384,18 +427,23 @@ static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf,
384 * reuse buf page, if SPLICE_F_MOVE is set 427 * reuse buf page, if SPLICE_F_MOVE is set
385 */ 428 */
386 if (sd->flags & SPLICE_F_MOVE) { 429 if (sd->flags & SPLICE_F_MOVE) {
430 /*
431 * If steal succeeds, buf->page is now pruned from the vm
432 * side (LRU and page cache) and we can reuse it.
433 */
387 if (buf->ops->steal(info, buf)) 434 if (buf->ops->steal(info, buf))
388 goto find_page; 435 goto find_page;
389 436
390 page = buf->page; 437 page = buf->page;
391 if (add_to_page_cache_lru(page, mapping, index, 438 if (add_to_page_cache(page, mapping, index, gfp_mask))
392 mapping_gfp_mask(mapping)))
393 goto find_page; 439 goto find_page;
440
441 if (!(buf->flags & PIPE_BUF_FLAG_LRU))
442 lru_cache_add(page);
394 } else { 443 } else {
395find_page: 444find_page:
396 ret = -ENOMEM; 445 ret = -ENOMEM;
397 page = find_or_create_page(mapping, index, 446 page = find_or_create_page(mapping, index, gfp_mask);
398 mapping_gfp_mask(mapping));
399 if (!page) 447 if (!page)
400 goto out; 448 goto out;
401 449
@@ -432,10 +480,13 @@ find_page:
432 } 480 }
433 481
434 ret = mapping->a_ops->prepare_write(file, page, 0, sd->len); 482 ret = mapping->a_ops->prepare_write(file, page, 0, sd->len);
435 if (ret) 483 if (ret == AOP_TRUNCATED_PAGE) {
484 page_cache_release(page);
485 goto find_page;
486 } else if (ret)
436 goto out; 487 goto out;
437 488
438 if (!buf->stolen) { 489 if (!(buf->flags & PIPE_BUF_FLAG_STOLEN)) {
439 char *dst = kmap_atomic(page, KM_USER0); 490 char *dst = kmap_atomic(page, KM_USER0);
440 491
441 memcpy(dst + offset, src + buf->offset, sd->len); 492 memcpy(dst + offset, src + buf->offset, sd->len);
@@ -444,16 +495,18 @@ find_page:
444 } 495 }
445 496
446 ret = mapping->a_ops->commit_write(file, page, 0, sd->len); 497 ret = mapping->a_ops->commit_write(file, page, 0, sd->len);
447 if (ret < 0) 498 if (ret == AOP_TRUNCATED_PAGE) {
499 page_cache_release(page);
500 goto find_page;
501 } else if (ret)
448 goto out; 502 goto out;
449 503
450 set_page_dirty(page); 504 balance_dirty_pages_ratelimited(mapping);
451 ret = write_one_page(page, 0);
452out: 505out:
453 if (ret < 0) 506 if (!(buf->flags & PIPE_BUF_FLAG_STOLEN)) {
454 unlock_page(page);
455 if (!buf->stolen)
456 page_cache_release(page); 507 page_cache_release(page);
508 unlock_page(page);
509 }
457 buf->ops->unmap(info, buf); 510 buf->ops->unmap(info, buf);
458 return ret; 511 return ret;
459} 512}
@@ -461,6 +514,11 @@ out:
461typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *, 514typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *,
462 struct splice_desc *); 515 struct splice_desc *);
463 516
517/*
518 * Pipe input worker. Most of this logic works like a regular pipe, the
519 * key here is the 'actor' worker passed in that actually moves the data
520 * to the wanted destination. See pipe_to_file/pipe_to_sendpage above.
521 */
464static ssize_t move_from_pipe(struct inode *inode, struct file *out, 522static ssize_t move_from_pipe(struct inode *inode, struct file *out,
465 size_t len, unsigned int flags, 523 size_t len, unsigned int flags,
466 splice_actor *actor) 524 splice_actor *actor)
@@ -527,6 +585,12 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out,
527 break; 585 break;
528 } 586 }
529 587
588 if (flags & SPLICE_F_NONBLOCK) {
589 if (!ret)
590 ret = -EAGAIN;
591 break;
592 }
593
530 if (signal_pending(current)) { 594 if (signal_pending(current)) {
531 if (!ret) 595 if (!ret)
532 ret = -ERESTARTSYS; 596 ret = -ERESTARTSYS;
@@ -556,21 +620,67 @@ static ssize_t move_from_pipe(struct inode *inode, struct file *out,
556 620
557} 621}
558 622
623/**
624 * generic_file_splice_write - splice data from a pipe to a file
625 * @inode: pipe inode
626 * @out: file to write to
627 * @len: number of bytes to splice
628 * @flags: splice modifier flags
629 *
630 * Will either move or copy pages (determined by @flags options) from
631 * the given pipe inode to the given file.
632 *
633 */
559ssize_t generic_file_splice_write(struct inode *inode, struct file *out, 634ssize_t generic_file_splice_write(struct inode *inode, struct file *out,
560 size_t len, unsigned int flags) 635 size_t len, unsigned int flags)
561{ 636{
562 return move_from_pipe(inode, out, len, flags, pipe_to_file); 637 struct address_space *mapping = out->f_mapping;
638 ssize_t ret = move_from_pipe(inode, out, len, flags, pipe_to_file);
639
640 /*
641 * if file or inode is SYNC and we actually wrote some data, sync it
642 */
643 if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(mapping->host))
644 && ret > 0) {
645 struct inode *inode = mapping->host;
646 int err;
647
648 mutex_lock(&inode->i_mutex);
649 err = generic_osync_inode(mapping->host, mapping,
650 OSYNC_METADATA|OSYNC_DATA);
651 mutex_unlock(&inode->i_mutex);
652
653 if (err)
654 ret = err;
655 }
656
657 return ret;
563} 658}
564 659
660EXPORT_SYMBOL(generic_file_splice_write);
661
662/**
663 * generic_splice_sendpage - splice data from a pipe to a socket
664 * @inode: pipe inode
665 * @out: socket to write to
666 * @len: number of bytes to splice
667 * @flags: splice modifier flags
668 *
669 * Will send @len bytes from the pipe to a network socket. No data copying
670 * is involved.
671 *
672 */
565ssize_t generic_splice_sendpage(struct inode *inode, struct file *out, 673ssize_t generic_splice_sendpage(struct inode *inode, struct file *out,
566 size_t len, unsigned int flags) 674 size_t len, unsigned int flags)
567{ 675{
568 return move_from_pipe(inode, out, len, flags, pipe_to_sendpage); 676 return move_from_pipe(inode, out, len, flags, pipe_to_sendpage);
569} 677}
570 678
571EXPORT_SYMBOL(generic_file_splice_write); 679EXPORT_SYMBOL(generic_splice_sendpage);
572EXPORT_SYMBOL(generic_file_splice_read);
573 680
681/*
682 * Attempt to initiate a splice from pipe to file.
683 */
574static long do_splice_from(struct inode *pipe, struct file *out, size_t len, 684static long do_splice_from(struct inode *pipe, struct file *out, size_t len,
575 unsigned int flags) 685 unsigned int flags)
576{ 686{
@@ -591,6 +701,9 @@ static long do_splice_from(struct inode *pipe, struct file *out, size_t len,
591 return out->f_op->splice_write(pipe, out, len, flags); 701 return out->f_op->splice_write(pipe, out, len, flags);
592} 702}
593 703
704/*
705 * Attempt to initiate a splice from a file to a pipe.
706 */
594static long do_splice_to(struct file *in, struct inode *pipe, size_t len, 707static long do_splice_to(struct file *in, struct inode *pipe, size_t len,
595 unsigned int flags) 708 unsigned int flags)
596{ 709{
@@ -619,6 +732,9 @@ static long do_splice_to(struct file *in, struct inode *pipe, size_t len,
619 return in->f_op->splice_read(in, pipe, len, flags); 732 return in->f_op->splice_read(in, pipe, len, flags);
620} 733}
621 734
735/*
736 * Determine where to splice to/from.
737 */
622static long do_splice(struct file *in, struct file *out, size_t len, 738static long do_splice(struct file *in, struct file *out, size_t len,
623 unsigned int flags) 739 unsigned int flags)
624{ 740{
diff --git a/fs/sync.c b/fs/sync.c
new file mode 100644
index 000000000000..8616006d2094
--- /dev/null
+++ b/fs/sync.c
@@ -0,0 +1,164 @@
1/*
2 * High-level sync()-related operations
3 */
4
5#include <linux/kernel.h>
6#include <linux/file.h>
7#include <linux/fs.h>
8#include <linux/module.h>
9#include <linux/writeback.h>
10#include <linux/syscalls.h>
11#include <linux/linkage.h>
12#include <linux/pagemap.h>
13
14#define VALID_FLAGS (SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE| \
15 SYNC_FILE_RANGE_WAIT_AFTER)
16
17/*
18 * sys_sync_file_range() permits finely controlled syncing over a segment of
19 * a file in the range offset .. (offset+nbytes-1) inclusive. If nbytes is
20 * zero then sys_sync_file_range() will operate from offset out to EOF.
21 *
22 * The flag bits are:
23 *
24 * SYNC_FILE_RANGE_WAIT_BEFORE: wait upon writeout of all pages in the range
25 * before performing the write.
26 *
27 * SYNC_FILE_RANGE_WRITE: initiate writeout of all those dirty pages in the
28 * range which are not presently under writeback.
29 *
30 * SYNC_FILE_RANGE_WAIT_AFTER: wait upon writeout of all pages in the range
31 * after performing the write.
32 *
33 * Useful combinations of the flag bits are:
34 *
35 * SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE: ensures that all pages
36 * in the range which were dirty on entry to sys_sync_file_range() are placed
37 * under writeout. This is a start-write-for-data-integrity operation.
38 *
39 * SYNC_FILE_RANGE_WRITE: start writeout of all dirty pages in the range which
40 * are not presently under writeout. This is an asynchronous flush-to-disk
41 * operation. Not suitable for data integrity operations.
42 *
43 * SYNC_FILE_RANGE_WAIT_BEFORE (or SYNC_FILE_RANGE_WAIT_AFTER): wait for
44 * completion of writeout of all pages in the range. This will be used after an
45 * earlier SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE operation to wait
46 * for that operation to complete and to return the result.
47 *
48 * SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE|SYNC_FILE_RANGE_WAIT_AFTER:
49 * a traditional sync() operation. This is a write-for-data-integrity operation
50 * which will ensure that all pages in the range which were dirty on entry to
51 * sys_sync_file_range() are committed to disk.
52 *
53 *
54 * SYNC_FILE_RANGE_WAIT_BEFORE and SYNC_FILE_RANGE_WAIT_AFTER will detect any
55 * I/O errors or ENOSPC conditions and will return those to the caller, after
56 * clearing the EIO and ENOSPC flags in the address_space.
57 *
58 * It should be noted that none of these operations write out the file's
59 * metadata. So unless the application is strictly performing overwrites of
60 * already-instantiated disk blocks, there are no guarantees here that the data
61 * will be available after a crash.
62 */
63asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes,
64 int flags)
65{
66 int ret;
67 struct file *file;
68 loff_t endbyte; /* inclusive */
69 int fput_needed;
70 umode_t i_mode;
71
72 ret = -EINVAL;
73 if (flags & ~VALID_FLAGS)
74 goto out;
75
76 endbyte = offset + nbytes;
77
78 if ((s64)offset < 0)
79 goto out;
80 if ((s64)endbyte < 0)
81 goto out;
82 if (endbyte < offset)
83 goto out;
84
85 if (sizeof(pgoff_t) == 4) {
86 if (offset >= (0x100000000ULL << PAGE_CACHE_SHIFT)) {
87 /*
88 * The range starts outside a 32 bit machine's
89 * pagecache addressing capabilities. Let it "succeed"
90 */
91 ret = 0;
92 goto out;
93 }
94 if (endbyte >= (0x100000000ULL << PAGE_CACHE_SHIFT)) {
95 /*
96 * Out to EOF
97 */
98 nbytes = 0;
99 }
100 }
101
102 if (nbytes == 0)
103 endbyte = -1;
104 else
105 endbyte--; /* inclusive */
106
107 ret = -EBADF;
108 file = fget_light(fd, &fput_needed);
109 if (!file)
110 goto out;
111
112 i_mode = file->f_dentry->d_inode->i_mode;
113 ret = -ESPIPE;
114 if (!S_ISREG(i_mode) && !S_ISBLK(i_mode) && !S_ISDIR(i_mode) &&
115 !S_ISLNK(i_mode))
116 goto out_put;
117
118 ret = do_sync_file_range(file, offset, endbyte, flags);
119out_put:
120 fput_light(file, fput_needed);
121out:
122 return ret;
123}
124
125/*
126 * `endbyte' is inclusive
127 */
128int do_sync_file_range(struct file *file, loff_t offset, loff_t endbyte,
129 int flags)
130{
131 int ret;
132 struct address_space *mapping;
133
134 mapping = file->f_mapping;
135 if (!mapping) {
136 ret = -EINVAL;
137 goto out;
138 }
139
140 ret = 0;
141 if (flags & SYNC_FILE_RANGE_WAIT_BEFORE) {
142 ret = wait_on_page_writeback_range(mapping,
143 offset >> PAGE_CACHE_SHIFT,
144 endbyte >> PAGE_CACHE_SHIFT);
145 if (ret < 0)
146 goto out;
147 }
148
149 if (flags & SYNC_FILE_RANGE_WRITE) {
150 ret = __filemap_fdatawrite_range(mapping, offset, endbyte,
151 WB_SYNC_NONE);
152 if (ret < 0)
153 goto out;
154 }
155
156 if (flags & SYNC_FILE_RANGE_WAIT_AFTER) {
157 ret = wait_on_page_writeback_range(mapping,
158 offset >> PAGE_CACHE_SHIFT,
159 endbyte >> PAGE_CACHE_SHIFT);
160 }
161out:
162 return ret;
163}
164EXPORT_SYMBOL_GPL(do_sync_file_range);
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index f26880a4785e..6cfdc9a87772 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -50,7 +50,7 @@ static struct sysfs_dirent * sysfs_new_dirent(struct sysfs_dirent * parent_sd,
50 return sd; 50 return sd;
51} 51}
52 52
53/** 53/*
54 * 54 *
55 * Return -EEXIST if there is already a sysfs element with the same name for 55 * Return -EEXIST if there is already a sysfs element with the same name for
56 * the same parent. 56 * the same parent.
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 830f76fa098c..f1cb1ddde511 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -183,7 +183,7 @@ fill_write_buffer(struct sysfs_buffer * buffer, const char __user * buf, size_t
183 return -ENOMEM; 183 return -ENOMEM;
184 184
185 if (count >= PAGE_SIZE) 185 if (count >= PAGE_SIZE)
186 count = PAGE_SIZE; 186 count = PAGE_SIZE - 1;
187 error = copy_from_user(buffer->page,buf,count); 187 error = copy_from_user(buffer->page,buf,count);
188 buffer->needs_read_fill = 1; 188 buffer->needs_read_fill = 1;
189 return error ? -EFAULT : count; 189 return error ? -EFAULT : count;
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 4c29ac41ac3e..f0b347bd12ca 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -175,8 +175,7 @@ const unsigned char * sysfs_get_name(struct sysfs_dirent *sd)
175 struct bin_attribute * bin_attr; 175 struct bin_attribute * bin_attr;
176 struct sysfs_symlink * sl; 176 struct sysfs_symlink * sl;
177 177
178 if (!sd || !sd->s_element) 178 BUG_ON(!sd || !sd->s_element);
179 BUG();
180 179
181 switch (sd->s_type) { 180 switch (sd->s_type) {
182 case SYSFS_DIR: 181 case SYSFS_DIR:
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c
index 8c66e9270dd6..d7074341ee87 100644
--- a/fs/sysv/dir.c
+++ b/fs/sysv/dir.c
@@ -253,8 +253,7 @@ int sysv_delete_entry(struct sysv_dir_entry *de, struct page *page)
253 253
254 lock_page(page); 254 lock_page(page);
255 err = mapping->a_ops->prepare_write(NULL, page, from, to); 255 err = mapping->a_ops->prepare_write(NULL, page, from, to);
256 if (err) 256 BUG_ON(err);
257 BUG();
258 de->inode = 0; 257 de->inode = 0;
259 err = dir_commit_chunk(page, from, to); 258 err = dir_commit_chunk(page, from, to);
260 dir_put_page(page); 259 dir_put_page(page);
@@ -353,8 +352,7 @@ void sysv_set_link(struct sysv_dir_entry *de, struct page *page,
353 352
354 lock_page(page); 353 lock_page(page);
355 err = page->mapping->a_ops->prepare_write(NULL, page, from, to); 354 err = page->mapping->a_ops->prepare_write(NULL, page, from, to);
356 if (err) 355 BUG_ON(err);
357 BUG();
358 de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino); 356 de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino);
359 err = dir_commit_chunk(page, from, to); 357 err = dir_commit_chunk(page, from, to);
360 dir_put_page(page); 358 dir_put_page(page);
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 81e0e8459af1..2983afd5e7fd 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -312,12 +312,10 @@ static int udf_get_block(struct inode *inode, sector_t block, struct buffer_head
312 err = 0; 312 err = 0;
313 313
314 bh = inode_getblk(inode, block, &err, &phys, &new); 314 bh = inode_getblk(inode, block, &err, &phys, &new);
315 if (bh) 315 BUG_ON(bh);
316 BUG();
317 if (err) 316 if (err)
318 goto abort; 317 goto abort;
319 if (!phys) 318 BUG_ON(!phys);
320 BUG();
321 319
322 if (new) 320 if (new)
323 set_buffer_new(bh_result); 321 set_buffer_new(bh_result);
diff --git a/fs/vfat/namei.c b/fs/vfat/namei.c
index ef46939c0c1a..a56cec3be5f0 100644
--- a/fs/vfat/namei.c
+++ b/fs/vfat/namei.c
@@ -185,24 +185,6 @@ static int vfat_valid_longname(const unsigned char *name, unsigned int len)
185 return -EINVAL; 185 return -EINVAL;
186 if (len >= 256) 186 if (len >= 256)
187 return -ENAMETOOLONG; 187 return -ENAMETOOLONG;
188
189 /* MS-DOS "device special files" */
190 if (len == 3 || (len > 3 && name[3] == '.')) { /* basename == 3 */
191 if (!strnicmp(name, "aux", 3) ||
192 !strnicmp(name, "con", 3) ||
193 !strnicmp(name, "nul", 3) ||
194 !strnicmp(name, "prn", 3))
195 return -EINVAL;
196 }
197 if (len == 4 || (len > 4 && name[4] == '.')) { /* basename == 4 */
198 /* "com1", "com2", ... */
199 if ('1' <= name[3] && name[3] <= '9') {
200 if (!strnicmp(name, "com", 3) ||
201 !strnicmp(name, "lpt", 3))
202 return -EINVAL;
203 }
204 }
205
206 return 0; 188 return 0;
207} 189}
208 190
diff --git a/fs/xfs/linux-2.6/xfs_file.c b/fs/xfs/linux-2.6/xfs_file.c
index 85997b1205f5..ae4c4754ed31 100644
--- a/fs/xfs/linux-2.6/xfs_file.c
+++ b/fs/xfs/linux-2.6/xfs_file.c
@@ -69,7 +69,6 @@ __xfs_file_read(
69 return rval; 69 return rval;
70} 70}
71 71
72
73STATIC ssize_t 72STATIC ssize_t
74xfs_file_aio_read( 73xfs_file_aio_read(
75 struct kiocb *iocb, 74 struct kiocb *iocb,
@@ -90,7 +89,6 @@ xfs_file_aio_read_invis(
90 return __xfs_file_read(iocb, buf, IO_ISAIO|IO_INVIS, count, pos); 89 return __xfs_file_read(iocb, buf, IO_ISAIO|IO_INVIS, count, pos);
91} 90}
92 91
93
94STATIC inline ssize_t 92STATIC inline ssize_t
95__xfs_file_write( 93__xfs_file_write(
96 struct kiocb *iocb, 94 struct kiocb *iocb,
@@ -113,7 +111,6 @@ __xfs_file_write(
113 return rval; 111 return rval;
114} 112}
115 113
116
117STATIC ssize_t 114STATIC ssize_t
118xfs_file_aio_write( 115xfs_file_aio_write(
119 struct kiocb *iocb, 116 struct kiocb *iocb,
@@ -134,7 +131,6 @@ xfs_file_aio_write_invis(
134 return __xfs_file_write(iocb, buf, IO_ISAIO|IO_INVIS, count, pos); 131 return __xfs_file_write(iocb, buf, IO_ISAIO|IO_INVIS, count, pos);
135} 132}
136 133
137
138STATIC inline ssize_t 134STATIC inline ssize_t
139__xfs_file_readv( 135__xfs_file_readv(
140 struct file *file, 136 struct file *file,
@@ -179,7 +175,6 @@ xfs_file_readv_invis(
179 return __xfs_file_readv(file, iov, IO_INVIS, nr_segs, ppos); 175 return __xfs_file_readv(file, iov, IO_INVIS, nr_segs, ppos);
180} 176}
181 177
182
183STATIC inline ssize_t 178STATIC inline ssize_t
184__xfs_file_writev( 179__xfs_file_writev(
185 struct file *file, 180 struct file *file,
@@ -204,7 +199,6 @@ __xfs_file_writev(
204 return rval; 199 return rval;
205} 200}
206 201
207
208STATIC ssize_t 202STATIC ssize_t
209xfs_file_writev( 203xfs_file_writev(
210 struct file *file, 204 struct file *file,
@@ -228,7 +222,7 @@ xfs_file_writev_invis(
228STATIC ssize_t 222STATIC ssize_t
229xfs_file_sendfile( 223xfs_file_sendfile(
230 struct file *filp, 224 struct file *filp,
231 loff_t *ppos, 225 loff_t *pos,
232 size_t count, 226 size_t count,
233 read_actor_t actor, 227 read_actor_t actor,
234 void *target) 228 void *target)
@@ -236,10 +230,80 @@ xfs_file_sendfile(
236 vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode); 230 vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode);
237 ssize_t rval; 231 ssize_t rval;
238 232
239 VOP_SENDFILE(vp, filp, ppos, 0, count, actor, target, NULL, rval); 233 VOP_SENDFILE(vp, filp, pos, 0, count, actor, target, NULL, rval);
240 return rval; 234 return rval;
241} 235}
242 236
237STATIC ssize_t
238xfs_file_sendfile_invis(
239 struct file *filp,
240 loff_t *pos,
241 size_t count,
242 read_actor_t actor,
243 void *target)
244{
245 vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode);
246 ssize_t rval;
247
248 VOP_SENDFILE(vp, filp, pos, IO_INVIS, count, actor, target, NULL, rval);
249 return rval;
250}
251
252STATIC ssize_t
253xfs_file_splice_read(
254 struct file *infilp,
255 struct inode *pipe,
256 size_t len,
257 unsigned int flags)
258{
259 vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode);
260 ssize_t rval;
261
262 VOP_SPLICE_READ(vp, infilp, pipe, len, flags, 0, NULL, rval);
263 return rval;
264}
265
266STATIC ssize_t
267xfs_file_splice_read_invis(
268 struct file *infilp,
269 struct inode *pipe,
270 size_t len,
271 unsigned int flags)
272{
273 vnode_t *vp = vn_from_inode(infilp->f_dentry->d_inode);
274 ssize_t rval;
275
276 VOP_SPLICE_READ(vp, infilp, pipe, len, flags, IO_INVIS, NULL, rval);
277 return rval;
278}
279
280STATIC ssize_t
281xfs_file_splice_write(
282 struct inode *pipe,
283 struct file *outfilp,
284 size_t len,
285 unsigned int flags)
286{
287 vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode);
288 ssize_t rval;
289
290 VOP_SPLICE_WRITE(vp, pipe, outfilp, len, flags, 0, NULL, rval);
291 return rval;
292}
293
294STATIC ssize_t
295xfs_file_splice_write_invis(
296 struct inode *pipe,
297 struct file *outfilp,
298 size_t len,
299 unsigned int flags)
300{
301 vnode_t *vp = vn_from_inode(outfilp->f_dentry->d_inode);
302 ssize_t rval;
303
304 VOP_SPLICE_WRITE(vp, pipe, outfilp, len, flags, IO_INVIS, NULL, rval);
305 return rval;
306}
243 307
244STATIC int 308STATIC int
245xfs_file_open( 309xfs_file_open(
@@ -251,13 +315,10 @@ xfs_file_open(
251 315
252 if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS) 316 if (!(filp->f_flags & O_LARGEFILE) && i_size_read(inode) > MAX_NON_LFS)
253 return -EFBIG; 317 return -EFBIG;
254
255 ASSERT(vp);
256 VOP_OPEN(vp, NULL, error); 318 VOP_OPEN(vp, NULL, error);
257 return -error; 319 return -error;
258} 320}
259 321
260
261STATIC int 322STATIC int
262xfs_file_release( 323xfs_file_release(
263 struct inode *inode, 324 struct inode *inode,
@@ -271,7 +332,6 @@ xfs_file_release(
271 return -error; 332 return -error;
272} 333}
273 334
274
275STATIC int 335STATIC int
276xfs_file_fsync( 336xfs_file_fsync(
277 struct file *filp, 337 struct file *filp,
@@ -285,21 +345,11 @@ xfs_file_fsync(
285 345
286 if (datasync) 346 if (datasync)
287 flags |= FSYNC_DATA; 347 flags |= FSYNC_DATA;
288
289 ASSERT(vp);
290 VOP_FSYNC(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1, error); 348 VOP_FSYNC(vp, flags, NULL, (xfs_off_t)0, (xfs_off_t)-1, error);
291 return -error; 349 return -error;
292} 350}
293 351
294/*
295 * xfs_file_readdir maps to VOP_READDIR().
296 * We need to build a uio, cred, ...
297 */
298
299#define nextdp(dp) ((struct xfs_dirent *)((char *)(dp) + (dp)->d_reclen))
300
301#ifdef CONFIG_XFS_DMAPI 352#ifdef CONFIG_XFS_DMAPI
302
303STATIC struct page * 353STATIC struct page *
304xfs_vm_nopage( 354xfs_vm_nopage(
305 struct vm_area_struct *area, 355 struct vm_area_struct *area,
@@ -319,10 +369,8 @@ xfs_vm_nopage(
319 369
320 return filemap_nopage(area, address, type); 370 return filemap_nopage(area, address, type);
321} 371}
322
323#endif /* CONFIG_XFS_DMAPI */ 372#endif /* CONFIG_XFS_DMAPI */
324 373
325
326STATIC int 374STATIC int
327xfs_file_readdir( 375xfs_file_readdir(
328 struct file *filp, 376 struct file *filp,
@@ -330,7 +378,7 @@ xfs_file_readdir(
330 filldir_t filldir) 378 filldir_t filldir)
331{ 379{
332 int error = 0; 380 int error = 0;
333 vnode_t *vp; 381 vnode_t *vp = vn_from_inode(filp->f_dentry->d_inode);
334 uio_t uio; 382 uio_t uio;
335 iovec_t iov; 383 iovec_t iov;
336 int eof = 0; 384 int eof = 0;
@@ -340,9 +388,6 @@ xfs_file_readdir(
340 xfs_off_t start_offset, curr_offset; 388 xfs_off_t start_offset, curr_offset;
341 xfs_dirent_t *dbp = NULL; 389 xfs_dirent_t *dbp = NULL;
342 390
343 vp = vn_from_inode(filp->f_dentry->d_inode);
344 ASSERT(vp);
345
346 /* Try fairly hard to get memory */ 391 /* Try fairly hard to get memory */
347 do { 392 do {
348 if ((read_buf = (caddr_t)kmalloc(rlen, GFP_KERNEL))) 393 if ((read_buf = (caddr_t)kmalloc(rlen, GFP_KERNEL)))
@@ -387,7 +432,7 @@ xfs_file_readdir(
387 } 432 }
388 size -= dbp->d_reclen; 433 size -= dbp->d_reclen;
389 curr_offset = (loff_t)dbp->d_off /* & 0x7fffffff */; 434 curr_offset = (loff_t)dbp->d_off /* & 0x7fffffff */;
390 dbp = nextdp(dbp); 435 dbp = (xfs_dirent_t *)((char *)dbp + dbp->d_reclen);
391 } 436 }
392 } 437 }
393done: 438done:
@@ -402,7 +447,6 @@ done:
402 return -error; 447 return -error;
403} 448}
404 449
405
406STATIC int 450STATIC int
407xfs_file_mmap( 451xfs_file_mmap(
408 struct file *filp, 452 struct file *filp,
@@ -457,11 +501,10 @@ xfs_file_ioctl_invis(
457 unsigned int cmd, 501 unsigned int cmd,
458 unsigned long arg) 502 unsigned long arg)
459{ 503{
460 int error;
461 struct inode *inode = filp->f_dentry->d_inode; 504 struct inode *inode = filp->f_dentry->d_inode;
462 vnode_t *vp = vn_from_inode(inode); 505 vnode_t *vp = vn_from_inode(inode);
506 int error;
463 507
464 ASSERT(vp);
465 VOP_IOCTL(vp, inode, filp, IO_INVIS, cmd, (void __user *)arg, error); 508 VOP_IOCTL(vp, inode, filp, IO_INVIS, cmd, (void __user *)arg, error);
466 VMODIFY(vp); 509 VMODIFY(vp);
467 510
@@ -537,6 +580,8 @@ const struct file_operations xfs_file_operations = {
537 .aio_read = xfs_file_aio_read, 580 .aio_read = xfs_file_aio_read,
538 .aio_write = xfs_file_aio_write, 581 .aio_write = xfs_file_aio_write,
539 .sendfile = xfs_file_sendfile, 582 .sendfile = xfs_file_sendfile,
583 .splice_read = xfs_file_splice_read,
584 .splice_write = xfs_file_splice_write,
540 .unlocked_ioctl = xfs_file_ioctl, 585 .unlocked_ioctl = xfs_file_ioctl,
541#ifdef CONFIG_COMPAT 586#ifdef CONFIG_COMPAT
542 .compat_ioctl = xfs_file_compat_ioctl, 587 .compat_ioctl = xfs_file_compat_ioctl,
@@ -558,7 +603,9 @@ const struct file_operations xfs_invis_file_operations = {
558 .writev = xfs_file_writev_invis, 603 .writev = xfs_file_writev_invis,
559 .aio_read = xfs_file_aio_read_invis, 604 .aio_read = xfs_file_aio_read_invis,
560 .aio_write = xfs_file_aio_write_invis, 605 .aio_write = xfs_file_aio_write_invis,
561 .sendfile = xfs_file_sendfile, 606 .sendfile = xfs_file_sendfile_invis,
607 .splice_read = xfs_file_splice_read_invis,
608 .splice_write = xfs_file_splice_write_invis,
562 .unlocked_ioctl = xfs_file_ioctl_invis, 609 .unlocked_ioctl = xfs_file_ioctl_invis,
563#ifdef CONFIG_COMPAT 610#ifdef CONFIG_COMPAT
564 .compat_ioctl = xfs_file_compat_invis_ioctl, 611 .compat_ioctl = xfs_file_compat_invis_ioctl,
diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h
index 1fe09f2d6519..e9fe43d74768 100644
--- a/fs/xfs/linux-2.6/xfs_linux.h
+++ b/fs/xfs/linux-2.6/xfs_linux.h
@@ -103,6 +103,7 @@
103 */ 103 */
104#undef HAVE_REFCACHE /* reference cache not needed for NFS in 2.6 */ 104#undef HAVE_REFCACHE /* reference cache not needed for NFS in 2.6 */
105#define HAVE_SENDFILE /* sendfile(2) exists in 2.6, but not in 2.4 */ 105#define HAVE_SENDFILE /* sendfile(2) exists in 2.6, but not in 2.4 */
106#define HAVE_SPLICE /* a splice(2) exists in 2.6, but not in 2.4 */
106#ifdef CONFIG_SMP 107#ifdef CONFIG_SMP
107#define HAVE_PERCPU_SB /* per cpu superblock counters are a 2.6 feature */ 108#define HAVE_PERCPU_SB /* per cpu superblock counters are a 2.6 feature */
108#else 109#else
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 84ddf1893894..90cd314acbaa 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -301,36 +301,23 @@ xfs_sendfile(
301 void *target, 301 void *target,
302 cred_t *credp) 302 cred_t *credp)
303{ 303{
304 xfs_inode_t *ip = XFS_BHVTOI(bdp);
305 xfs_mount_t *mp = ip->i_mount;
304 ssize_t ret; 306 ssize_t ret;
305 xfs_fsize_t n;
306 xfs_inode_t *ip;
307 xfs_mount_t *mp;
308 vnode_t *vp;
309
310 ip = XFS_BHVTOI(bdp);
311 vp = BHV_TO_VNODE(bdp);
312 mp = ip->i_mount;
313 307
314 XFS_STATS_INC(xs_read_calls); 308 XFS_STATS_INC(xs_read_calls);
315 309 if (XFS_FORCED_SHUTDOWN(mp))
316 n = XFS_MAXIOFFSET(mp) - *offset;
317 if ((n <= 0) || (count == 0))
318 return 0;
319
320 if (n < count)
321 count = n;
322
323 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
324 return -EIO; 310 return -EIO;
325 311
326 xfs_ilock(ip, XFS_IOLOCK_SHARED); 312 xfs_ilock(ip, XFS_IOLOCK_SHARED);
327 313
328 if (DM_EVENT_ENABLED(vp->v_vfsp, ip, DM_EVENT_READ) && 314 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
329 (!(ioflags & IO_INVIS))) { 315 (!(ioflags & IO_INVIS))) {
330 vrwlock_t locktype = VRWLOCK_READ; 316 vrwlock_t locktype = VRWLOCK_READ;
331 int error; 317 int error;
332 318
333 error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp), *offset, count, 319 error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp),
320 *offset, count,
334 FILP_DELAY_FLAG(filp), &locktype); 321 FILP_DELAY_FLAG(filp), &locktype);
335 if (error) { 322 if (error) {
336 xfs_iunlock(ip, XFS_IOLOCK_SHARED); 323 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
@@ -340,12 +327,96 @@ xfs_sendfile(
340 xfs_rw_enter_trace(XFS_SENDFILE_ENTER, &ip->i_iocore, 327 xfs_rw_enter_trace(XFS_SENDFILE_ENTER, &ip->i_iocore,
341 (void *)(unsigned long)target, count, *offset, ioflags); 328 (void *)(unsigned long)target, count, *offset, ioflags);
342 ret = generic_file_sendfile(filp, offset, count, actor, target); 329 ret = generic_file_sendfile(filp, offset, count, actor, target);
330 if (ret > 0)
331 XFS_STATS_ADD(xs_read_bytes, ret);
343 332
344 xfs_iunlock(ip, XFS_IOLOCK_SHARED); 333 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
334 return ret;
335}
345 336
337ssize_t
338xfs_splice_read(
339 bhv_desc_t *bdp,
340 struct file *infilp,
341 struct inode *pipe,
342 size_t count,
343 int flags,
344 int ioflags,
345 cred_t *credp)
346{
347 xfs_inode_t *ip = XFS_BHVTOI(bdp);
348 xfs_mount_t *mp = ip->i_mount;
349 ssize_t ret;
350
351 XFS_STATS_INC(xs_read_calls);
352 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
353 return -EIO;
354
355 xfs_ilock(ip, XFS_IOLOCK_SHARED);
356
357 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_READ) &&
358 (!(ioflags & IO_INVIS))) {
359 vrwlock_t locktype = VRWLOCK_READ;
360 int error;
361
362 error = XFS_SEND_DATA(mp, DM_EVENT_READ, BHV_TO_VNODE(bdp),
363 infilp->f_pos, count,
364 FILP_DELAY_FLAG(infilp), &locktype);
365 if (error) {
366 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
367 return -error;
368 }
369 }
370 xfs_rw_enter_trace(XFS_SPLICE_READ_ENTER, &ip->i_iocore,
371 pipe, count, infilp->f_pos, ioflags);
372 ret = generic_file_splice_read(infilp, pipe, count, flags);
346 if (ret > 0) 373 if (ret > 0)
347 XFS_STATS_ADD(xs_read_bytes, ret); 374 XFS_STATS_ADD(xs_read_bytes, ret);
348 375
376 xfs_iunlock(ip, XFS_IOLOCK_SHARED);
377 return ret;
378}
379
380ssize_t
381xfs_splice_write(
382 bhv_desc_t *bdp,
383 struct inode *pipe,
384 struct file *outfilp,
385 size_t count,
386 int flags,
387 int ioflags,
388 cred_t *credp)
389{
390 xfs_inode_t *ip = XFS_BHVTOI(bdp);
391 xfs_mount_t *mp = ip->i_mount;
392 ssize_t ret;
393
394 XFS_STATS_INC(xs_write_calls);
395 if (XFS_FORCED_SHUTDOWN(ip->i_mount))
396 return -EIO;
397
398 xfs_ilock(ip, XFS_IOLOCK_EXCL);
399
400 if (DM_EVENT_ENABLED(BHV_TO_VNODE(bdp)->v_vfsp, ip, DM_EVENT_WRITE) &&
401 (!(ioflags & IO_INVIS))) {
402 vrwlock_t locktype = VRWLOCK_WRITE;
403 int error;
404
405 error = XFS_SEND_DATA(mp, DM_EVENT_WRITE, BHV_TO_VNODE(bdp),
406 outfilp->f_pos, count,
407 FILP_DELAY_FLAG(outfilp), &locktype);
408 if (error) {
409 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
410 return -error;
411 }
412 }
413 xfs_rw_enter_trace(XFS_SPLICE_WRITE_ENTER, &ip->i_iocore,
414 pipe, count, outfilp->f_pos, ioflags);
415 ret = generic_file_splice_write(pipe, outfilp, count, flags);
416 if (ret > 0)
417 XFS_STATS_ADD(xs_write_bytes, ret);
418
419 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
349 return ret; 420 return ret;
350} 421}
351 422
@@ -363,7 +434,7 @@ xfs_zero_last_block(
363 xfs_fsize_t end_size) 434 xfs_fsize_t end_size)
364{ 435{
365 xfs_fileoff_t last_fsb; 436 xfs_fileoff_t last_fsb;
366 xfs_mount_t *mp; 437 xfs_mount_t *mp = io->io_mount;
367 int nimaps; 438 int nimaps;
368 int zero_offset; 439 int zero_offset;
369 int zero_len; 440 int zero_len;
@@ -373,8 +444,6 @@ xfs_zero_last_block(
373 444
374 ASSERT(ismrlocked(io->io_lock, MR_UPDATE) != 0); 445 ASSERT(ismrlocked(io->io_lock, MR_UPDATE) != 0);
375 446
376 mp = io->io_mount;
377
378 zero_offset = XFS_B_FSB_OFFSET(mp, isize); 447 zero_offset = XFS_B_FSB_OFFSET(mp, isize);
379 if (zero_offset == 0) { 448 if (zero_offset == 0) {
380 /* 449 /*
@@ -405,10 +474,9 @@ xfs_zero_last_block(
405 * don't deadlock when the buffer cache calls back to us. 474 * don't deadlock when the buffer cache calls back to us.
406 */ 475 */
407 XFS_IUNLOCK(mp, io, XFS_ILOCK_EXCL| XFS_EXTSIZE_RD); 476 XFS_IUNLOCK(mp, io, XFS_ILOCK_EXCL| XFS_EXTSIZE_RD);
408 loff = XFS_FSB_TO_B(mp, last_fsb);
409 477
478 loff = XFS_FSB_TO_B(mp, last_fsb);
410 zero_len = mp->m_sb.sb_blocksize - zero_offset; 479 zero_len = mp->m_sb.sb_blocksize - zero_offset;
411
412 error = xfs_iozero(ip, loff + zero_offset, zero_len, end_size); 480 error = xfs_iozero(ip, loff + zero_offset, zero_len, end_size);
413 481
414 XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD); 482 XFS_ILOCK(mp, io, XFS_ILOCK_EXCL|XFS_EXTSIZE_RD);
@@ -441,7 +509,7 @@ xfs_zero_eof(
441 xfs_fileoff_t zero_count_fsb; 509 xfs_fileoff_t zero_count_fsb;
442 xfs_fileoff_t last_fsb; 510 xfs_fileoff_t last_fsb;
443 xfs_extlen_t buf_len_fsb; 511 xfs_extlen_t buf_len_fsb;
444 xfs_mount_t *mp; 512 xfs_mount_t *mp = io->io_mount;
445 int nimaps; 513 int nimaps;
446 int error = 0; 514 int error = 0;
447 xfs_bmbt_irec_t imap; 515 xfs_bmbt_irec_t imap;
@@ -450,8 +518,6 @@ xfs_zero_eof(
450 ASSERT(ismrlocked(io->io_iolock, MR_UPDATE)); 518 ASSERT(ismrlocked(io->io_iolock, MR_UPDATE));
451 ASSERT(offset > isize); 519 ASSERT(offset > isize);
452 520
453 mp = io->io_mount;
454
455 /* 521 /*
456 * First handle zeroing the block on which isize resides. 522 * First handle zeroing the block on which isize resides.
457 * We only zero a part of that block so it is handled specially. 523 * We only zero a part of that block so it is handled specially.
diff --git a/fs/xfs/linux-2.6/xfs_lrw.h b/fs/xfs/linux-2.6/xfs_lrw.h
index 38864a88d42d..eaa5659713fb 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.h
+++ b/fs/xfs/linux-2.6/xfs_lrw.h
@@ -60,6 +60,8 @@ struct xfs_iomap;
60#define XFS_IOMAP_ALLOC_ENTER 25 60#define XFS_IOMAP_ALLOC_ENTER 25
61#define XFS_IOMAP_ALLOC_MAP 26 61#define XFS_IOMAP_ALLOC_MAP 26
62#define XFS_IOMAP_UNWRITTEN 27 62#define XFS_IOMAP_UNWRITTEN 27
63#define XFS_SPLICE_READ_ENTER 28
64#define XFS_SPLICE_WRITE_ENTER 29
63extern void xfs_rw_enter_trace(int, struct xfs_iocore *, 65extern void xfs_rw_enter_trace(int, struct xfs_iocore *,
64 void *, size_t, loff_t, int); 66 void *, size_t, loff_t, int);
65extern void xfs_inval_cached_trace(struct xfs_iocore *, 67extern void xfs_inval_cached_trace(struct xfs_iocore *,
@@ -78,6 +80,7 @@ extern int xfs_bmap(struct bhv_desc *, xfs_off_t, ssize_t, int,
78 struct xfs_iomap *, int *); 80 struct xfs_iomap *, int *);
79extern int xfsbdstrat(struct xfs_mount *, struct xfs_buf *); 81extern int xfsbdstrat(struct xfs_mount *, struct xfs_buf *);
80extern int xfs_bdstrat_cb(struct xfs_buf *); 82extern int xfs_bdstrat_cb(struct xfs_buf *);
83extern int xfs_dev_is_read_only(struct xfs_mount *, char *);
81 84
82extern int xfs_zero_eof(struct vnode *, struct xfs_iocore *, xfs_off_t, 85extern int xfs_zero_eof(struct vnode *, struct xfs_iocore *, xfs_off_t,
83 xfs_fsize_t, xfs_fsize_t); 86 xfs_fsize_t, xfs_fsize_t);
@@ -90,7 +93,11 @@ extern ssize_t xfs_write(struct bhv_desc *, struct kiocb *,
90extern ssize_t xfs_sendfile(struct bhv_desc *, struct file *, 93extern ssize_t xfs_sendfile(struct bhv_desc *, struct file *,
91 loff_t *, int, size_t, read_actor_t, 94 loff_t *, int, size_t, read_actor_t,
92 void *, struct cred *); 95 void *, struct cred *);
93 96extern ssize_t xfs_splice_read(struct bhv_desc *, struct file *,
94extern int xfs_dev_is_read_only(struct xfs_mount *, char *); 97 struct inode *, size_t, int, int,
98 struct cred *);
99extern ssize_t xfs_splice_write(struct bhv_desc *, struct inode *,
100 struct file *, size_t, int, int,
101 struct cred *);
95 102
96#endif /* __XFS_LRW_H__ */ 103#endif /* __XFS_LRW_H__ */
diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c
index 1884300417e3..68f4793e8a11 100644
--- a/fs/xfs/linux-2.6/xfs_super.c
+++ b/fs/xfs/linux-2.6/xfs_super.c
@@ -67,7 +67,8 @@ mempool_t *xfs_ioend_pool;
67 67
68STATIC struct xfs_mount_args * 68STATIC struct xfs_mount_args *
69xfs_args_allocate( 69xfs_args_allocate(
70 struct super_block *sb) 70 struct super_block *sb,
71 int silent)
71{ 72{
72 struct xfs_mount_args *args; 73 struct xfs_mount_args *args;
73 74
@@ -80,8 +81,8 @@ xfs_args_allocate(
80 args->flags |= XFSMNT_DIRSYNC; 81 args->flags |= XFSMNT_DIRSYNC;
81 if (sb->s_flags & MS_SYNCHRONOUS) 82 if (sb->s_flags & MS_SYNCHRONOUS)
82 args->flags |= XFSMNT_WSYNC; 83 args->flags |= XFSMNT_WSYNC;
83 84 if (silent)
84 /* Default to 32 bit inodes on Linux all the time */ 85 args->flags |= XFSMNT_QUIET;
85 args->flags |= XFSMNT_32BITINODES; 86 args->flags |= XFSMNT_32BITINODES;
86 87
87 return args; 88 return args;
@@ -719,7 +720,7 @@ xfs_fs_remount(
719 char *options) 720 char *options)
720{ 721{
721 vfs_t *vfsp = vfs_from_sb(sb); 722 vfs_t *vfsp = vfs_from_sb(sb);
722 struct xfs_mount_args *args = xfs_args_allocate(sb); 723 struct xfs_mount_args *args = xfs_args_allocate(sb, 0);
723 int error; 724 int error;
724 725
725 VFS_PARSEARGS(vfsp, options, args, 1, error); 726 VFS_PARSEARGS(vfsp, options, args, 1, error);
@@ -825,7 +826,7 @@ xfs_fs_fill_super(
825{ 826{
826 vnode_t *rootvp; 827 vnode_t *rootvp;
827 struct vfs *vfsp = vfs_allocate(sb); 828 struct vfs *vfsp = vfs_allocate(sb);
828 struct xfs_mount_args *args = xfs_args_allocate(sb); 829 struct xfs_mount_args *args = xfs_args_allocate(sb, silent);
829 struct kstatfs statvfs; 830 struct kstatfs statvfs;
830 int error, error2; 831 int error, error2;
831 832
diff --git a/fs/xfs/linux-2.6/xfs_vnode.h b/fs/xfs/linux-2.6/xfs_vnode.h
index 06f5845e9568..6f1c79a28f8b 100644
--- a/fs/xfs/linux-2.6/xfs_vnode.h
+++ b/fs/xfs/linux-2.6/xfs_vnode.h
@@ -173,6 +173,12 @@ typedef ssize_t (*vop_write_t)(bhv_desc_t *, struct kiocb *,
173typedef ssize_t (*vop_sendfile_t)(bhv_desc_t *, struct file *, 173typedef ssize_t (*vop_sendfile_t)(bhv_desc_t *, struct file *,
174 loff_t *, int, size_t, read_actor_t, 174 loff_t *, int, size_t, read_actor_t,
175 void *, struct cred *); 175 void *, struct cred *);
176typedef ssize_t (*vop_splice_read_t)(bhv_desc_t *, struct file *,
177 struct inode *, size_t, int, int,
178 struct cred *);
179typedef ssize_t (*vop_splice_write_t)(bhv_desc_t *, struct inode *,
180 struct file *, size_t, int, int,
181 struct cred *);
176typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *, 182typedef int (*vop_ioctl_t)(bhv_desc_t *, struct inode *, struct file *,
177 int, unsigned int, void __user *); 183 int, unsigned int, void __user *);
178typedef int (*vop_getattr_t)(bhv_desc_t *, struct vattr *, int, 184typedef int (*vop_getattr_t)(bhv_desc_t *, struct vattr *, int,
@@ -231,6 +237,8 @@ typedef struct vnodeops {
231 vop_read_t vop_read; 237 vop_read_t vop_read;
232 vop_write_t vop_write; 238 vop_write_t vop_write;
233 vop_sendfile_t vop_sendfile; 239 vop_sendfile_t vop_sendfile;
240 vop_splice_read_t vop_splice_read;
241 vop_splice_write_t vop_splice_write;
234 vop_ioctl_t vop_ioctl; 242 vop_ioctl_t vop_ioctl;
235 vop_getattr_t vop_getattr; 243 vop_getattr_t vop_getattr;
236 vop_setattr_t vop_setattr; 244 vop_setattr_t vop_setattr;
@@ -276,6 +284,10 @@ typedef struct vnodeops {
276 rv = _VOP_(vop_write, vp)((vp)->v_fbhv,file,iov,segs,offset,ioflags,cr) 284 rv = _VOP_(vop_write, vp)((vp)->v_fbhv,file,iov,segs,offset,ioflags,cr)
277#define VOP_SENDFILE(vp,f,off,ioflags,cnt,act,targ,cr,rv) \ 285#define VOP_SENDFILE(vp,f,off,ioflags,cnt,act,targ,cr,rv) \
278 rv = _VOP_(vop_sendfile, vp)((vp)->v_fbhv,f,off,ioflags,cnt,act,targ,cr) 286 rv = _VOP_(vop_sendfile, vp)((vp)->v_fbhv,f,off,ioflags,cnt,act,targ,cr)
287#define VOP_SPLICE_READ(vp,f,pipe,cnt,fl,iofl,cr,rv) \
288 rv = _VOP_(vop_splice_read, vp)((vp)->v_fbhv,f,pipe,cnt,fl,iofl,cr)
289#define VOP_SPLICE_WRITE(vp,f,pipe,cnt,fl,iofl,cr,rv) \
290 rv = _VOP_(vop_splice_write, vp)((vp)->v_fbhv,f,pipe,cnt,fl,iofl,cr)
279#define VOP_BMAP(vp,of,sz,rw,b,n,rv) \ 291#define VOP_BMAP(vp,of,sz,rw,b,n,rv) \
280 rv = _VOP_(vop_bmap, vp)((vp)->v_fbhv,of,sz,rw,b,n) 292 rv = _VOP_(vop_bmap, vp)((vp)->v_fbhv,of,sz,rw,b,n)
281#define VOP_OPEN(vp, cr, rv) \ 293#define VOP_OPEN(vp, cr, rv) \
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 73c1e5e80c07..7fb5eca9bd50 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -2624,7 +2624,7 @@ xfs_qm_vop_chown_reserve(
2624{ 2624{
2625 int error; 2625 int error;
2626 xfs_mount_t *mp; 2626 xfs_mount_t *mp;
2627 uint delblks, blkflags; 2627 uint delblks, blkflags, prjflags = 0;
2628 xfs_dquot_t *unresudq, *unresgdq, *delblksudq, *delblksgdq; 2628 xfs_dquot_t *unresudq, *unresgdq, *delblksudq, *delblksgdq;
2629 2629
2630 ASSERT(XFS_ISLOCKED_INODE(ip)); 2630 ASSERT(XFS_ISLOCKED_INODE(ip));
@@ -2650,10 +2650,13 @@ xfs_qm_vop_chown_reserve(
2650 } 2650 }
2651 } 2651 }
2652 if (XFS_IS_OQUOTA_ON(ip->i_mount) && gdqp) { 2652 if (XFS_IS_OQUOTA_ON(ip->i_mount) && gdqp) {
2653 if ((XFS_IS_GQUOTA_ON(ip->i_mount) && 2653 if (XFS_IS_PQUOTA_ON(ip->i_mount) &&
2654 ip->i_d.di_gid != be32_to_cpu(gdqp->q_core.d_id)) || 2654 ip->i_d.di_projid != be32_to_cpu(gdqp->q_core.d_id))
2655 (XFS_IS_PQUOTA_ON(ip->i_mount) && 2655 prjflags = XFS_QMOPT_ENOSPC;
2656 ip->i_d.di_projid != be32_to_cpu(gdqp->q_core.d_id))) { 2656
2657 if (prjflags ||
2658 (XFS_IS_GQUOTA_ON(ip->i_mount) &&
2659 ip->i_d.di_gid != be32_to_cpu(gdqp->q_core.d_id))) {
2657 delblksgdq = gdqp; 2660 delblksgdq = gdqp;
2658 if (delblks) { 2661 if (delblks) {
2659 ASSERT(ip->i_gdquot); 2662 ASSERT(ip->i_gdquot);
@@ -2664,7 +2667,7 @@ xfs_qm_vop_chown_reserve(
2664 2667
2665 if ((error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount, 2668 if ((error = xfs_trans_reserve_quota_bydquots(tp, ip->i_mount,
2666 delblksudq, delblksgdq, ip->i_d.di_nblocks, 1, 2669 delblksudq, delblksgdq, ip->i_d.di_nblocks, 1,
2667 flags | blkflags))) 2670 flags | blkflags | prjflags)))
2668 return (error); 2671 return (error);
2669 2672
2670 /* 2673 /*
@@ -2681,7 +2684,7 @@ xfs_qm_vop_chown_reserve(
2681 ASSERT(unresudq || unresgdq); 2684 ASSERT(unresudq || unresgdq);
2682 if ((error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount, 2685 if ((error = xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
2683 delblksudq, delblksgdq, (xfs_qcnt_t)delblks, 0, 2686 delblksudq, delblksgdq, (xfs_qcnt_t)delblks, 0,
2684 flags | blkflags))) 2687 flags | blkflags | prjflags)))
2685 return (error); 2688 return (error);
2686 xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount, 2689 xfs_trans_reserve_quota_bydquots(NULL, ip->i_mount,
2687 unresudq, unresgdq, -((xfs_qcnt_t)delblks), 0, 2690 unresudq, unresgdq, -((xfs_qcnt_t)delblks), 0,
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c
index d8e131ec0aa8..9168918db252 100644
--- a/fs/xfs/quota/xfs_trans_dquot.c
+++ b/fs/xfs/quota/xfs_trans_dquot.c
@@ -595,12 +595,19 @@ xfs_trans_unreserve_and_mod_dquots(
595 } 595 }
596} 596}
597 597
598STATIC int
599xfs_quota_error(uint flags)
600{
601 if (flags & XFS_QMOPT_ENOSPC)
602 return ENOSPC;
603 return EDQUOT;
604}
605
598/* 606/*
599 * This reserves disk blocks and inodes against a dquot. 607 * This reserves disk blocks and inodes against a dquot.
600 * Flags indicate if the dquot is to be locked here and also 608 * Flags indicate if the dquot is to be locked here and also
601 * if the blk reservation is for RT or regular blocks. 609 * if the blk reservation is for RT or regular blocks.
602 * Sending in XFS_QMOPT_FORCE_RES flag skips the quota check. 610 * Sending in XFS_QMOPT_FORCE_RES flag skips the quota check.
603 * Returns EDQUOT if quota is exceeded.
604 */ 611 */
605STATIC int 612STATIC int
606xfs_trans_dqresv( 613xfs_trans_dqresv(
@@ -666,19 +673,15 @@ xfs_trans_dqresv(
666 */ 673 */
667 if (hardlimit > 0ULL && 674 if (hardlimit > 0ULL &&
668 (hardlimit <= nblks + *resbcountp)) { 675 (hardlimit <= nblks + *resbcountp)) {
669 error = EDQUOT; 676 error = xfs_quota_error(flags);
670 goto error_return; 677 goto error_return;
671 } 678 }
672 679
673 if (softlimit > 0ULL && 680 if (softlimit > 0ULL &&
674 (softlimit <= nblks + *resbcountp)) { 681 (softlimit <= nblks + *resbcountp)) {
675 /*
676 * If timer or warnings has expired,
677 * return EDQUOT
678 */
679 if ((timer != 0 && get_seconds() > timer) || 682 if ((timer != 0 && get_seconds() > timer) ||
680 (warns != 0 && warns >= warnlimit)) { 683 (warns != 0 && warns >= warnlimit)) {
681 error = EDQUOT; 684 error = xfs_quota_error(flags);
682 goto error_return; 685 goto error_return;
683 } 686 }
684 } 687 }
@@ -695,16 +698,12 @@ xfs_trans_dqresv(
695 if (!softlimit) 698 if (!softlimit)
696 softlimit = q->qi_isoftlimit; 699 softlimit = q->qi_isoftlimit;
697 if (hardlimit > 0ULL && count >= hardlimit) { 700 if (hardlimit > 0ULL && count >= hardlimit) {
698 error = EDQUOT; 701 error = xfs_quota_error(flags);
699 goto error_return; 702 goto error_return;
700 } else if (softlimit > 0ULL && count >= softlimit) { 703 } else if (softlimit > 0ULL && count >= softlimit) {
701 /*
702 * If timer or warnings has expired,
703 * return EDQUOT
704 */
705 if ((timer != 0 && get_seconds() > timer) || 704 if ((timer != 0 && get_seconds() > timer) ||
706 (warns != 0 && warns >= warnlimit)) { 705 (warns != 0 && warns >= warnlimit)) {
707 error = EDQUOT; 706 error = xfs_quota_error(flags);
708 goto error_return; 707 goto error_return;
709 } 708 }
710 } 709 }
@@ -751,13 +750,14 @@ error_return:
751 750
752 751
753/* 752/*
754 * Given a dquot(s), make disk block and/or inode reservations against them. 753 * Given dquot(s), make disk block and/or inode reservations against them.
755 * The fact that this does the reservation against both the usr and 754 * The fact that this does the reservation against both the usr and
756 * grp quotas is important, because this follows a both-or-nothing 755 * grp/prj quotas is important, because this follows a both-or-nothing
757 * approach. 756 * approach.
758 * 757 *
759 * flags = XFS_QMOPT_DQLOCK indicate if dquot(s) need to be locked. 758 * flags = XFS_QMOPT_DQLOCK indicate if dquot(s) need to be locked.
760 * XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown. 759 * XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown.
760 * XFS_QMOPT_ENOSPC returns ENOSPC not EDQUOT. Used by pquota.
761 * XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks 761 * XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks
762 * XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks 762 * XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks
763 * dquots are unlocked on return, if they were not locked by caller. 763 * dquots are unlocked on return, if they were not locked by caller.
@@ -772,25 +772,27 @@ xfs_trans_reserve_quota_bydquots(
772 long ninos, 772 long ninos,
773 uint flags) 773 uint flags)
774{ 774{
775 int resvd; 775 int resvd = 0, error;
776 776
777 if (! XFS_IS_QUOTA_ON(mp)) 777 if (!XFS_IS_QUOTA_ON(mp))
778 return (0); 778 return 0;
779 779
780 if (tp && tp->t_dqinfo == NULL) 780 if (tp && tp->t_dqinfo == NULL)
781 xfs_trans_alloc_dqinfo(tp); 781 xfs_trans_alloc_dqinfo(tp);
782 782
783 ASSERT(flags & XFS_QMOPT_RESBLK_MASK); 783 ASSERT(flags & XFS_QMOPT_RESBLK_MASK);
784 resvd = 0;
785 784
786 if (udqp) { 785 if (udqp) {
787 if (xfs_trans_dqresv(tp, mp, udqp, nblks, ninos, flags)) 786 error = xfs_trans_dqresv(tp, mp, udqp, nblks, ninos,
788 return (EDQUOT); 787 (flags & ~XFS_QMOPT_ENOSPC));
788 if (error)
789 return error;
789 resvd = 1; 790 resvd = 1;
790 } 791 }
791 792
792 if (gdqp) { 793 if (gdqp) {
793 if (xfs_trans_dqresv(tp, mp, gdqp, nblks, ninos, flags)) { 794 error = xfs_trans_dqresv(tp, mp, gdqp, nblks, ninos, flags);
795 if (error) {
794 /* 796 /*
795 * can't do it, so backout previous reservation 797 * can't do it, so backout previous reservation
796 */ 798 */
@@ -799,14 +801,14 @@ xfs_trans_reserve_quota_bydquots(
799 xfs_trans_dqresv(tp, mp, udqp, 801 xfs_trans_dqresv(tp, mp, udqp,
800 -nblks, -ninos, flags); 802 -nblks, -ninos, flags);
801 } 803 }
802 return (EDQUOT); 804 return error;
803 } 805 }
804 } 806 }
805 807
806 /* 808 /*
807 * Didn't change anything critical, so, no need to log 809 * Didn't change anything critical, so, no need to log
808 */ 810 */
809 return (0); 811 return 0;
810} 812}
811 813
812 814
@@ -814,8 +816,6 @@ xfs_trans_reserve_quota_bydquots(
814 * Lock the dquot and change the reservation if we can. 816 * Lock the dquot and change the reservation if we can.
815 * This doesn't change the actual usage, just the reservation. 817 * This doesn't change the actual usage, just the reservation.
816 * The inode sent in is locked. 818 * The inode sent in is locked.
817 *
818 * Returns 0 on success, EDQUOT or other errors otherwise
819 */ 819 */
820STATIC int 820STATIC int
821xfs_trans_reserve_quota_nblks( 821xfs_trans_reserve_quota_nblks(
@@ -824,20 +824,24 @@ xfs_trans_reserve_quota_nblks(
824 xfs_inode_t *ip, 824 xfs_inode_t *ip,
825 long nblks, 825 long nblks,
826 long ninos, 826 long ninos,
827 uint type) 827 uint flags)
828{ 828{
829 int error; 829 int error;
830 830
831 if (!XFS_IS_QUOTA_ON(mp)) 831 if (!XFS_IS_QUOTA_ON(mp))
832 return (0); 832 return 0;
833 if (XFS_IS_PQUOTA_ON(mp))
834 flags |= XFS_QMOPT_ENOSPC;
833 835
834 ASSERT(ip->i_ino != mp->m_sb.sb_uquotino); 836 ASSERT(ip->i_ino != mp->m_sb.sb_uquotino);
835 ASSERT(ip->i_ino != mp->m_sb.sb_gquotino); 837 ASSERT(ip->i_ino != mp->m_sb.sb_gquotino);
836 838
837 ASSERT(XFS_ISLOCKED_INODE_EXCL(ip)); 839 ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
838 ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount)); 840 ASSERT(XFS_IS_QUOTA_RUNNING(ip->i_mount));
839 ASSERT((type & ~XFS_QMOPT_FORCE_RES) == XFS_TRANS_DQ_RES_RTBLKS || 841 ASSERT((flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) ==
840 (type & ~XFS_QMOPT_FORCE_RES) == XFS_TRANS_DQ_RES_BLKS); 842 XFS_TRANS_DQ_RES_RTBLKS ||
843 (flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) ==
844 XFS_TRANS_DQ_RES_BLKS);
841 845
842 /* 846 /*
843 * Reserve nblks against these dquots, with trans as the mediator. 847 * Reserve nblks against these dquots, with trans as the mediator.
@@ -845,8 +849,8 @@ xfs_trans_reserve_quota_nblks(
845 error = xfs_trans_reserve_quota_bydquots(tp, mp, 849 error = xfs_trans_reserve_quota_bydquots(tp, mp,
846 ip->i_udquot, ip->i_gdquot, 850 ip->i_udquot, ip->i_gdquot,
847 nblks, ninos, 851 nblks, ninos,
848 type); 852 flags);
849 return (error); 853 return error;
850} 854}
851 855
852/* 856/*
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index d384e489705f..26939d364bc4 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -4719,18 +4719,17 @@ xfs_bmapi(
4719 /* 4719 /*
4720 * Make a transaction-less quota reservation for 4720 * Make a transaction-less quota reservation for
4721 * delayed allocation blocks. This number gets 4721 * delayed allocation blocks. This number gets
4722 * adjusted later. 4722 * adjusted later. We return if we haven't
4723 * We return EDQUOT if we haven't allocated 4723 * allocated blocks already inside this loop.
4724 * blks already inside this loop;
4725 */ 4724 */
4726 if (XFS_TRANS_RESERVE_QUOTA_NBLKS( 4725 if ((error = XFS_TRANS_RESERVE_QUOTA_NBLKS(
4727 mp, NULL, ip, (long)alen, 0, 4726 mp, NULL, ip, (long)alen, 0,
4728 rt ? XFS_QMOPT_RES_RTBLKS : 4727 rt ? XFS_QMOPT_RES_RTBLKS :
4729 XFS_QMOPT_RES_REGBLKS)) { 4728 XFS_QMOPT_RES_REGBLKS))) {
4730 if (n == 0) { 4729 if (n == 0) {
4731 *nmap = 0; 4730 *nmap = 0;
4732 ASSERT(cur == NULL); 4731 ASSERT(cur == NULL);
4733 return XFS_ERROR(EDQUOT); 4732 return error;
4734 } 4733 }
4735 break; 4734 break;
4736 } 4735 }
diff --git a/fs/xfs/xfs_bmap.h b/fs/xfs/xfs_bmap.h
index f83399c89ce3..8e0d73d9ccc4 100644
--- a/fs/xfs/xfs_bmap.h
+++ b/fs/xfs/xfs_bmap.h
@@ -353,10 +353,11 @@ xfs_check_nostate_extents(
353 xfs_extnum_t num); 353 xfs_extnum_t num);
354 354
355/* 355/*
356 * Call xfs_bmap_do_search_extents() to search for the extent 356 * Search the extent records for the entry containing block bno.
357 * record containing block bno. If in multi-level in-core extent 357 * If bno lies in a hole, point to the next entry. If bno lies
358 * allocation mode, find and extract the target extent buffer, 358 * past eof, *eofp will be set, and *prevp will contain the last
359 * otherwise just use the direct extent list. 359 * entry (null if none). Else, *lastxp will be set to the index
360 * of the found entry; *gotp will contain the entry.
360 */ 361 */
361xfs_bmbt_rec_t * 362xfs_bmbt_rec_t *
362xfs_bmap_search_multi_extents(struct xfs_ifork *, xfs_fileoff_t, int *, 363xfs_bmap_search_multi_extents(struct xfs_ifork *, xfs_fileoff_t, int *,
diff --git a/fs/xfs/xfs_clnt.h b/fs/xfs/xfs_clnt.h
index 022fff62085b..5b7eb81453be 100644
--- a/fs/xfs/xfs_clnt.h
+++ b/fs/xfs/xfs_clnt.h
@@ -68,6 +68,7 @@ struct xfs_mount_args {
68 * enforcement */ 68 * enforcement */
69#define XFSMNT_PQUOTAENF 0x00000040 /* IRIX project quota limit 69#define XFSMNT_PQUOTAENF 0x00000040 /* IRIX project quota limit
70 * enforcement */ 70 * enforcement */
71#define XFSMNT_QUIET 0x00000080 /* don't report mount errors */
71#define XFSMNT_NOALIGN 0x00000200 /* don't allocate at 72#define XFSMNT_NOALIGN 0x00000200 /* don't allocate at
72 * stripe boundaries*/ 73 * stripe boundaries*/
73#define XFSMNT_RETERR 0x00000400 /* return error to user */ 74#define XFSMNT_RETERR 0x00000400 /* return error to user */
diff --git a/fs/xfs/xfs_error.h b/fs/xfs/xfs_error.h
index 26b8e709a569..bc43163456ef 100644
--- a/fs/xfs/xfs_error.h
+++ b/fs/xfs/xfs_error.h
@@ -186,4 +186,7 @@ extern void xfs_fs_cmn_err(int level, struct xfs_mount *mp, char *fmt, ...);
186#define xfs_fs_repair_cmn_err(level, mp, fmt, args...) \ 186#define xfs_fs_repair_cmn_err(level, mp, fmt, args...) \
187 xfs_fs_cmn_err(level, mp, fmt " Unmount and run xfs_repair.", ## args) 187 xfs_fs_cmn_err(level, mp, fmt " Unmount and run xfs_repair.", ## args)
188 188
189#define xfs_fs_mount_cmn_err(f, fmt, args...) \
190 ((f & XFS_MFSI_QUIET)? cmn_err(CE_WARN, "XFS: " fmt, ## args) : (void)0)
191
189#endif /* __XFS_ERROR_H__ */ 192#endif /* __XFS_ERROR_H__ */
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 72e7e78bfff8..049fabb7f7e0 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -213,7 +213,8 @@ xfs_mount_free(
213STATIC int 213STATIC int
214xfs_mount_validate_sb( 214xfs_mount_validate_sb(
215 xfs_mount_t *mp, 215 xfs_mount_t *mp,
216 xfs_sb_t *sbp) 216 xfs_sb_t *sbp,
217 int flags)
217{ 218{
218 /* 219 /*
219 * If the log device and data device have the 220 * If the log device and data device have the
@@ -223,33 +224,29 @@ xfs_mount_validate_sb(
223 * a volume filesystem in a non-volume manner. 224 * a volume filesystem in a non-volume manner.
224 */ 225 */
225 if (sbp->sb_magicnum != XFS_SB_MAGIC) { 226 if (sbp->sb_magicnum != XFS_SB_MAGIC) {
226 cmn_err(CE_WARN, "XFS: bad magic number"); 227 xfs_fs_mount_cmn_err(flags, "bad magic number");
227 return XFS_ERROR(EWRONGFS); 228 return XFS_ERROR(EWRONGFS);
228 } 229 }
229 230
230 if (!XFS_SB_GOOD_VERSION(sbp)) { 231 if (!XFS_SB_GOOD_VERSION(sbp)) {
231 cmn_err(CE_WARN, "XFS: bad version"); 232 xfs_fs_mount_cmn_err(flags, "bad version");
232 return XFS_ERROR(EWRONGFS); 233 return XFS_ERROR(EWRONGFS);
233 } 234 }
234 235
235 if (unlikely( 236 if (unlikely(
236 sbp->sb_logstart == 0 && mp->m_logdev_targp == mp->m_ddev_targp)) { 237 sbp->sb_logstart == 0 && mp->m_logdev_targp == mp->m_ddev_targp)) {
237 cmn_err(CE_WARN, 238 xfs_fs_mount_cmn_err(flags,
238 "XFS: filesystem is marked as having an external log; " 239 "filesystem is marked as having an external log; "
239 "specify logdev on the\nmount command line."); 240 "specify logdev on the\nmount command line.");
240 XFS_CORRUPTION_ERROR("xfs_mount_validate_sb(1)", 241 return XFS_ERROR(EINVAL);
241 XFS_ERRLEVEL_HIGH, mp, sbp);
242 return XFS_ERROR(EFSCORRUPTED);
243 } 242 }
244 243
245 if (unlikely( 244 if (unlikely(
246 sbp->sb_logstart != 0 && mp->m_logdev_targp != mp->m_ddev_targp)) { 245 sbp->sb_logstart != 0 && mp->m_logdev_targp != mp->m_ddev_targp)) {
247 cmn_err(CE_WARN, 246 xfs_fs_mount_cmn_err(flags,
248 "XFS: filesystem is marked as having an internal log; " 247 "filesystem is marked as having an internal log; "
249 "don't specify logdev on\nthe mount command line."); 248 "do not specify logdev on\nthe mount command line.");
250 XFS_CORRUPTION_ERROR("xfs_mount_validate_sb(2)", 249 return XFS_ERROR(EINVAL);
251 XFS_ERRLEVEL_HIGH, mp, sbp);
252 return XFS_ERROR(EFSCORRUPTED);
253 } 250 }
254 251
255 /* 252 /*
@@ -274,9 +271,7 @@ xfs_mount_validate_sb(
274 (sbp->sb_rextsize * sbp->sb_blocksize > XFS_MAX_RTEXTSIZE) || 271 (sbp->sb_rextsize * sbp->sb_blocksize > XFS_MAX_RTEXTSIZE) ||
275 (sbp->sb_rextsize * sbp->sb_blocksize < XFS_MIN_RTEXTSIZE) || 272 (sbp->sb_rextsize * sbp->sb_blocksize < XFS_MIN_RTEXTSIZE) ||
276 (sbp->sb_imax_pct > 100 || sbp->sb_imax_pct < 1))) { 273 (sbp->sb_imax_pct > 100 || sbp->sb_imax_pct < 1))) {
277 cmn_err(CE_WARN, "XFS: SB sanity check 1 failed"); 274 xfs_fs_mount_cmn_err(flags, "SB sanity check 1 failed");
278 XFS_CORRUPTION_ERROR("xfs_mount_validate_sb(3)",
279 XFS_ERRLEVEL_LOW, mp, sbp);
280 return XFS_ERROR(EFSCORRUPTED); 275 return XFS_ERROR(EFSCORRUPTED);
281 } 276 }
282 277
@@ -289,9 +284,7 @@ xfs_mount_validate_sb(
289 (xfs_drfsbno_t)sbp->sb_agcount * sbp->sb_agblocks || 284 (xfs_drfsbno_t)sbp->sb_agcount * sbp->sb_agblocks ||
290 sbp->sb_dblocks < (xfs_drfsbno_t)(sbp->sb_agcount - 1) * 285 sbp->sb_dblocks < (xfs_drfsbno_t)(sbp->sb_agcount - 1) *
291 sbp->sb_agblocks + XFS_MIN_AG_BLOCKS)) { 286 sbp->sb_agblocks + XFS_MIN_AG_BLOCKS)) {
292 cmn_err(CE_WARN, "XFS: SB sanity check 2 failed"); 287 xfs_fs_mount_cmn_err(flags, "SB sanity check 2 failed");
293 XFS_ERROR_REPORT("xfs_mount_validate_sb(4)",
294 XFS_ERRLEVEL_LOW, mp);
295 return XFS_ERROR(EFSCORRUPTED); 288 return XFS_ERROR(EFSCORRUPTED);
296 } 289 }
297 290
@@ -307,15 +300,13 @@ xfs_mount_validate_sb(
307 (sbp->sb_dblocks << (sbp->sb_blocklog - BBSHIFT)) > UINT_MAX || 300 (sbp->sb_dblocks << (sbp->sb_blocklog - BBSHIFT)) > UINT_MAX ||
308 (sbp->sb_rblocks << (sbp->sb_blocklog - BBSHIFT)) > UINT_MAX)) { 301 (sbp->sb_rblocks << (sbp->sb_blocklog - BBSHIFT)) > UINT_MAX)) {
309#endif 302#endif
310 cmn_err(CE_WARN, 303 xfs_fs_mount_cmn_err(flags,
311 "XFS: File system is too large to be mounted on this system."); 304 "file system too large to be mounted on this system.");
312 return XFS_ERROR(E2BIG); 305 return XFS_ERROR(E2BIG);
313 } 306 }
314 307
315 if (unlikely(sbp->sb_inprogress)) { 308 if (unlikely(sbp->sb_inprogress)) {
316 cmn_err(CE_WARN, "XFS: file system busy"); 309 xfs_fs_mount_cmn_err(flags, "file system busy");
317 XFS_ERROR_REPORT("xfs_mount_validate_sb(5)",
318 XFS_ERRLEVEL_LOW, mp);
319 return XFS_ERROR(EFSCORRUPTED); 310 return XFS_ERROR(EFSCORRUPTED);
320 } 311 }
321 312
@@ -323,8 +314,8 @@ xfs_mount_validate_sb(
323 * Version 1 directory format has never worked on Linux. 314 * Version 1 directory format has never worked on Linux.
324 */ 315 */
325 if (unlikely(!XFS_SB_VERSION_HASDIRV2(sbp))) { 316 if (unlikely(!XFS_SB_VERSION_HASDIRV2(sbp))) {
326 cmn_err(CE_WARN, 317 xfs_fs_mount_cmn_err(flags,
327 "XFS: Attempted to mount file system using version 1 directory format"); 318 "file system using version 1 directory format");
328 return XFS_ERROR(ENOSYS); 319 return XFS_ERROR(ENOSYS);
329 } 320 }
330 321
@@ -332,11 +323,11 @@ xfs_mount_validate_sb(
332 * Until this is fixed only page-sized or smaller data blocks work. 323 * Until this is fixed only page-sized or smaller data blocks work.
333 */ 324 */
334 if (unlikely(sbp->sb_blocksize > PAGE_SIZE)) { 325 if (unlikely(sbp->sb_blocksize > PAGE_SIZE)) {
335 cmn_err(CE_WARN, 326 xfs_fs_mount_cmn_err(flags,
336 "XFS: Attempted to mount file system with blocksize %d bytes", 327 "file system with blocksize %d bytes",
337 sbp->sb_blocksize); 328 sbp->sb_blocksize);
338 cmn_err(CE_WARN, 329 xfs_fs_mount_cmn_err(flags,
339 "XFS: Only page-sized (%ld) or less blocksizes currently work.", 330 "only pagesize (%ld) or less will currently work.",
340 PAGE_SIZE); 331 PAGE_SIZE);
341 return XFS_ERROR(ENOSYS); 332 return XFS_ERROR(ENOSYS);
342 } 333 }
@@ -484,7 +475,7 @@ xfs_xlatesb(
484 * Does the initial read of the superblock. 475 * Does the initial read of the superblock.
485 */ 476 */
486int 477int
487xfs_readsb(xfs_mount_t *mp) 478xfs_readsb(xfs_mount_t *mp, int flags)
488{ 479{
489 unsigned int sector_size; 480 unsigned int sector_size;
490 unsigned int extra_flags; 481 unsigned int extra_flags;
@@ -506,7 +497,7 @@ xfs_readsb(xfs_mount_t *mp)
506 bp = xfs_buf_read_flags(mp->m_ddev_targp, XFS_SB_DADDR, 497 bp = xfs_buf_read_flags(mp->m_ddev_targp, XFS_SB_DADDR,
507 BTOBB(sector_size), extra_flags); 498 BTOBB(sector_size), extra_flags);
508 if (!bp || XFS_BUF_ISERROR(bp)) { 499 if (!bp || XFS_BUF_ISERROR(bp)) {
509 cmn_err(CE_WARN, "XFS: SB read failed"); 500 xfs_fs_mount_cmn_err(flags, "SB read failed");
510 error = bp ? XFS_BUF_GETERROR(bp) : ENOMEM; 501 error = bp ? XFS_BUF_GETERROR(bp) : ENOMEM;
511 goto fail; 502 goto fail;
512 } 503 }
@@ -520,9 +511,9 @@ xfs_readsb(xfs_mount_t *mp)
520 sbp = XFS_BUF_TO_SBP(bp); 511 sbp = XFS_BUF_TO_SBP(bp);
521 xfs_xlatesb(XFS_BUF_PTR(bp), &(mp->m_sb), 1, XFS_SB_ALL_BITS); 512 xfs_xlatesb(XFS_BUF_PTR(bp), &(mp->m_sb), 1, XFS_SB_ALL_BITS);
522 513
523 error = xfs_mount_validate_sb(mp, &(mp->m_sb)); 514 error = xfs_mount_validate_sb(mp, &(mp->m_sb), flags);
524 if (error) { 515 if (error) {
525 cmn_err(CE_WARN, "XFS: SB validate failed"); 516 xfs_fs_mount_cmn_err(flags, "SB validate failed");
526 goto fail; 517 goto fail;
527 } 518 }
528 519
@@ -530,8 +521,8 @@ xfs_readsb(xfs_mount_t *mp)
530 * We must be able to do sector-sized and sector-aligned IO. 521 * We must be able to do sector-sized and sector-aligned IO.
531 */ 522 */
532 if (sector_size > mp->m_sb.sb_sectsize) { 523 if (sector_size > mp->m_sb.sb_sectsize) {
533 cmn_err(CE_WARN, 524 xfs_fs_mount_cmn_err(flags,
534 "XFS: device supports only %u byte sectors (not %u)", 525 "device supports only %u byte sectors (not %u)",
535 sector_size, mp->m_sb.sb_sectsize); 526 sector_size, mp->m_sb.sb_sectsize);
536 error = ENOSYS; 527 error = ENOSYS;
537 goto fail; 528 goto fail;
@@ -548,7 +539,7 @@ xfs_readsb(xfs_mount_t *mp)
548 bp = xfs_buf_read_flags(mp->m_ddev_targp, XFS_SB_DADDR, 539 bp = xfs_buf_read_flags(mp->m_ddev_targp, XFS_SB_DADDR,
549 BTOBB(sector_size), extra_flags); 540 BTOBB(sector_size), extra_flags);
550 if (!bp || XFS_BUF_ISERROR(bp)) { 541 if (!bp || XFS_BUF_ISERROR(bp)) {
551 cmn_err(CE_WARN, "XFS: SB re-read failed"); 542 xfs_fs_mount_cmn_err(flags, "SB re-read failed");
552 error = bp ? XFS_BUF_GETERROR(bp) : ENOMEM; 543 error = bp ? XFS_BUF_GETERROR(bp) : ENOMEM;
553 goto fail; 544 goto fail;
554 } 545 }
@@ -678,7 +669,7 @@ xfs_mountfs(
678 int error = 0; 669 int error = 0;
679 670
680 if (mp->m_sb_bp == NULL) { 671 if (mp->m_sb_bp == NULL) {
681 if ((error = xfs_readsb(mp))) { 672 if ((error = xfs_readsb(mp, mfsi_flags))) {
682 return error; 673 return error;
683 } 674 }
684 } 675 }
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 66cbee79864e..668ad23fd37c 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -510,9 +510,12 @@ xfs_preferred_iosize(xfs_mount_t *mp)
510 */ 510 */
511#define XFS_MFSI_SECOND 0x01 /* Secondary mount -- skip stuff */ 511#define XFS_MFSI_SECOND 0x01 /* Secondary mount -- skip stuff */
512#define XFS_MFSI_CLIENT 0x02 /* Is a client -- skip lots of stuff */ 512#define XFS_MFSI_CLIENT 0x02 /* Is a client -- skip lots of stuff */
513/* XFS_MFSI_RRINODES */
513#define XFS_MFSI_NOUNLINK 0x08 /* Skip unlinked inode processing in */ 514#define XFS_MFSI_NOUNLINK 0x08 /* Skip unlinked inode processing in */
514 /* log recovery */ 515 /* log recovery */
515#define XFS_MFSI_NO_QUOTACHECK 0x10 /* Skip quotacheck processing */ 516#define XFS_MFSI_NO_QUOTACHECK 0x10 /* Skip quotacheck processing */
517/* XFS_MFSI_CONVERT_SUNIT */
518#define XFS_MFSI_QUIET 0x40 /* Be silent if mount errors found */
516 519
517/* 520/*
518 * Macros for getting from mount to vfs and back. 521 * Macros for getting from mount to vfs and back.
@@ -581,7 +584,7 @@ extern int xfs_mod_incore_sb_unlocked(xfs_mount_t *, xfs_sb_field_t,
581extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *, 584extern int xfs_mod_incore_sb_batch(xfs_mount_t *, xfs_mod_sb_t *,
582 uint, int); 585 uint, int);
583extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int); 586extern struct xfs_buf *xfs_getsb(xfs_mount_t *, int);
584extern int xfs_readsb(xfs_mount_t *mp); 587extern int xfs_readsb(xfs_mount_t *, int);
585extern void xfs_freesb(xfs_mount_t *); 588extern void xfs_freesb(xfs_mount_t *);
586extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int); 589extern void xfs_do_force_shutdown(bhv_desc_t *, int, char *, int);
587extern int xfs_syncsub(xfs_mount_t *, int, int, int *); 590extern int xfs_syncsub(xfs_mount_t *, int, int, int *);
diff --git a/fs/xfs/xfs_quota.h b/fs/xfs/xfs_quota.h
index 4f6a034de7f7..7fbef974bce6 100644
--- a/fs/xfs/xfs_quota.h
+++ b/fs/xfs/xfs_quota.h
@@ -196,10 +196,11 @@ typedef struct xfs_qoff_logformat {
196#define XFS_QMOPT_QUOTAOFF 0x0000080 /* quotas are being turned off */ 196#define XFS_QMOPT_QUOTAOFF 0x0000080 /* quotas are being turned off */
197#define XFS_QMOPT_UMOUNTING 0x0000100 /* filesys is being unmounted */ 197#define XFS_QMOPT_UMOUNTING 0x0000100 /* filesys is being unmounted */
198#define XFS_QMOPT_DOLOG 0x0000200 /* log buf changes (in quotacheck) */ 198#define XFS_QMOPT_DOLOG 0x0000200 /* log buf changes (in quotacheck) */
199#define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if necessary */ 199#define XFS_QMOPT_DOWARN 0x0000400 /* increase warning cnt if needed */
200#define XFS_QMOPT_ILOCKED 0x0000800 /* inode is already locked (excl) */ 200#define XFS_QMOPT_ILOCKED 0x0000800 /* inode is already locked (excl) */
201#define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot, if damaged. */ 201#define XFS_QMOPT_DQREPAIR 0x0001000 /* repair dquot if damaged */
202#define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */ 202#define XFS_QMOPT_GQUOTA 0x0002000 /* group dquot requested */
203#define XFS_QMOPT_ENOSPC 0x0004000 /* enospc instead of edquot (prj) */
203 204
204/* 205/*
205 * flags to xfs_trans_mod_dquot to indicate which field needs to be 206 * flags to xfs_trans_mod_dquot to indicate which field needs to be
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c
index 504d2a80747a..f0e09ca14139 100644
--- a/fs/xfs/xfs_vfsops.c
+++ b/fs/xfs/xfs_vfsops.c
@@ -442,6 +442,9 @@ xfs_mount(
442 p = vfs_bhv_lookup(vfsp, VFS_POSITION_IO); 442 p = vfs_bhv_lookup(vfsp, VFS_POSITION_IO);
443 mp->m_io_ops = p ? *(xfs_ioops_t *) vfs_bhv_custom(p) : xfs_iocore_xfs; 443 mp->m_io_ops = p ? *(xfs_ioops_t *) vfs_bhv_custom(p) : xfs_iocore_xfs;
444 444
445 if (args->flags & XFSMNT_QUIET)
446 flags |= XFS_MFSI_QUIET;
447
445 /* 448 /*
446 * Open real time and log devices - order is important. 449 * Open real time and log devices - order is important.
447 */ 450 */
@@ -492,7 +495,7 @@ xfs_mount(
492 error = xfs_start_flags(vfsp, args, mp); 495 error = xfs_start_flags(vfsp, args, mp);
493 if (error) 496 if (error)
494 goto error1; 497 goto error1;
495 error = xfs_readsb(mp); 498 error = xfs_readsb(mp, flags);
496 if (error) 499 if (error)
497 goto error1; 500 goto error1;
498 error = xfs_finish_flags(vfsp, args, mp); 501 error = xfs_finish_flags(vfsp, args, mp);
@@ -1697,8 +1700,9 @@ xfs_parseargs(
1697 int dsunit, dswidth, vol_dsunit, vol_dswidth; 1700 int dsunit, dswidth, vol_dsunit, vol_dswidth;
1698 int iosize; 1701 int iosize;
1699 1702
1700 args->flags2 |= XFSMNT2_COMPAT_IOSIZE;
1701 args->flags |= XFSMNT_IDELETE; 1703 args->flags |= XFSMNT_IDELETE;
1704 args->flags |= XFSMNT_BARRIER;
1705 args->flags2 |= XFSMNT2_COMPAT_IOSIZE;
1702 1706
1703 if (!options) 1707 if (!options)
1704 goto done; 1708 goto done;
@@ -1947,8 +1951,6 @@ xfs_showargs(
1947 seq_printf(m, "," MNTOPT_IKEEP); 1951 seq_printf(m, "," MNTOPT_IKEEP);
1948 if (!(mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE)) 1952 if (!(mp->m_flags & XFS_MOUNT_COMPAT_IOSIZE))
1949 seq_printf(m, "," MNTOPT_LARGEIO); 1953 seq_printf(m, "," MNTOPT_LARGEIO);
1950 if (mp->m_flags & XFS_MOUNT_BARRIER)
1951 seq_printf(m, "," MNTOPT_BARRIER);
1952 1954
1953 if (!(vfsp->vfs_flag & VFS_32BITINODES)) 1955 if (!(vfsp->vfs_flag & VFS_32BITINODES))
1954 seq_printf(m, "," MNTOPT_64BITINODE); 1956 seq_printf(m, "," MNTOPT_64BITINODE);
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c
index de49601919c1..fa71b305ba5c 100644
--- a/fs/xfs/xfs_vnodeops.c
+++ b/fs/xfs/xfs_vnodeops.c
@@ -4649,6 +4649,10 @@ vnodeops_t xfs_vnodeops = {
4649#ifdef HAVE_SENDFILE 4649#ifdef HAVE_SENDFILE
4650 .vop_sendfile = xfs_sendfile, 4650 .vop_sendfile = xfs_sendfile,
4651#endif 4651#endif
4652#ifdef HAVE_SPLICE
4653 .vop_splice_read = xfs_splice_read,
4654 .vop_splice_write = xfs_splice_write,
4655#endif
4652 .vop_write = xfs_write, 4656 .vop_write = xfs_write,
4653 .vop_ioctl = xfs_ioctl, 4657 .vop_ioctl = xfs_ioctl,
4654 .vop_getattr = xfs_getattr, 4658 .vop_getattr = xfs_getattr,