diff options
Diffstat (limited to 'fs/cifs')
-rw-r--r-- | fs/cifs/cifs_dfs_ref.c | 1 | ||||
-rw-r--r-- | fs/cifs/cifs_fs_sb.h | 3 | ||||
-rw-r--r-- | fs/cifs/cifs_spnego.c | 1 | ||||
-rw-r--r-- | fs/cifs/cifs_unicode.c | 1 | ||||
-rw-r--r-- | fs/cifs/cifsacl.c | 1 | ||||
-rw-r--r-- | fs/cifs/cifsencrypt.c | 1 | ||||
-rw-r--r-- | fs/cifs/cifsfs.c | 11 | ||||
-rw-r--r-- | fs/cifs/cifsglob.h | 1 | ||||
-rw-r--r-- | fs/cifs/cifssmb.c | 35 | ||||
-rw-r--r-- | fs/cifs/connect.c | 1 | ||||
-rw-r--r-- | fs/cifs/dns_resolve.c | 1 | ||||
-rw-r--r-- | fs/cifs/file.c | 29 | ||||
-rw-r--r-- | fs/cifs/inode.c | 1 | ||||
-rw-r--r-- | fs/cifs/link.c | 1 | ||||
-rw-r--r-- | fs/cifs/readdir.c | 1 | ||||
-rw-r--r-- | fs/cifs/sess.c | 1 | ||||
-rw-r--r-- | fs/cifs/smbencrypt.c | 1 | ||||
-rw-r--r-- | fs/cifs/transport.c | 1 | ||||
-rw-r--r-- | fs/cifs/xattr.c | 1 |
19 files changed, 89 insertions, 4 deletions
diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c index b1d61d0bdfc..78e4d2a3a68 100644 --- a/fs/cifs/cifs_dfs_ref.c +++ b/fs/cifs/cifs_dfs_ref.c @@ -15,6 +15,7 @@ #include <linux/dcache.h> #include <linux/mount.h> #include <linux/namei.h> +#include <linux/slab.h> #include <linux/vfs.h> #include <linux/fs.h> #include "cifsglob.h" diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h index 4797787c6a4..246a167cb91 100644 --- a/fs/cifs/cifs_fs_sb.h +++ b/fs/cifs/cifs_fs_sb.h @@ -18,6 +18,8 @@ #ifndef _CIFS_FS_SB_H #define _CIFS_FS_SB_H +#include <linux/backing-dev.h> + #define CIFS_MOUNT_NO_PERM 1 /* do not do client vfs_perm check */ #define CIFS_MOUNT_SET_UID 2 /* set current's euid in create etc. */ #define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */ @@ -50,5 +52,6 @@ struct cifs_sb_info { #ifdef CONFIG_CIFS_DFS_UPCALL char *mountdata; /* mount options received at mount time */ #endif + struct backing_dev_info bdi; }; #endif /* _CIFS_FS_SB_H */ diff --git a/fs/cifs/cifs_spnego.c b/fs/cifs/cifs_spnego.c index 8ec7736ce95..310d12f69a9 100644 --- a/fs/cifs/cifs_spnego.c +++ b/fs/cifs/cifs_spnego.c @@ -20,6 +20,7 @@ */ #include <linux/list.h> +#include <linux/slab.h> #include <linux/string.h> #include <keys/user-type.h> #include <linux/key-type.h> diff --git a/fs/cifs/cifs_unicode.c b/fs/cifs/cifs_unicode.c index 714a542cbaf..d07676bd76d 100644 --- a/fs/cifs/cifs_unicode.c +++ b/fs/cifs/cifs_unicode.c @@ -19,6 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <linux/fs.h> +#include <linux/slab.h> #include "cifs_unicode.h" #include "cifs_uniupr.h" #include "cifspdu.h" diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index 7dfe0842a6f..9b716d044bb 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c @@ -22,6 +22,7 @@ */ #include <linux/fs.h> +#include <linux/slab.h> #include "cifspdu.h" #include "cifsglob.h" #include "cifsacl.h" diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index 7efe1745494..fbe986430d0 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c @@ -20,6 +20,7 @@ */ #include <linux/fs.h> +#include <linux/slab.h> #include "cifspdu.h" #include "cifsglob.h" #include "cifs_debug.h" diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 5183bc2a191..ad235d604a0 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -103,6 +103,12 @@ cifs_read_super(struct super_block *sb, void *data, if (cifs_sb == NULL) return -ENOMEM; + rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY); + if (rc) { + kfree(cifs_sb); + return rc; + } + #ifdef CONFIG_CIFS_DFS_UPCALL /* copy mount params to sb for use in submounts */ /* BB: should we move this after the mount so we @@ -115,6 +121,7 @@ cifs_read_super(struct super_block *sb, void *data, int len = strlen(data); cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL); if (cifs_sb->mountdata == NULL) { + bdi_destroy(&cifs_sb->bdi); kfree(sb->s_fs_info); sb->s_fs_info = NULL; return -ENOMEM; @@ -135,6 +142,7 @@ cifs_read_super(struct super_block *sb, void *data, sb->s_magic = CIFS_MAGIC_NUMBER; sb->s_op = &cifs_super_ops; + sb->s_bdi = &cifs_sb->bdi; /* if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512) sb->s_blocksize = cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */ @@ -183,6 +191,7 @@ out_mount_failed: } #endif unload_nls(cifs_sb->local_nls); + bdi_destroy(&cifs_sb->bdi); kfree(cifs_sb); } return rc; @@ -214,6 +223,7 @@ cifs_put_super(struct super_block *sb) #endif unload_nls(cifs_sb->local_nls); + bdi_destroy(&cifs_sb->bdi); kfree(cifs_sb); unlock_kernel(); @@ -808,6 +818,7 @@ const struct file_operations cifs_file_direct_nobrl_ops = { .release = cifs_close, .fsync = cifs_fsync, .flush = cifs_flush, + .mmap = cifs_file_mmap, .splice_read = generic_file_splice_read, #ifdef CONFIG_CIFS_POSIX .unlocked_ioctl = cifs_ioctl, diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 63c89d1d70b..ecf0ffbe2b6 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -18,6 +18,7 @@ */ #include <linux/in.h> #include <linux/in6.h> +#include <linux/slab.h> #include <linux/slow-work.h> #include "cifs_fs_sb.h" #include "cifsacl.h" diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 7cc7f83e931..5d3f29fef53 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -30,6 +30,7 @@ #include <linux/fs.h> #include <linux/kernel.h> #include <linux/vfs.h> +#include <linux/slab.h> #include <linux/posix_acl_xattr.h> #include <asm/uaccess.h> #include "cifspdu.h" @@ -1430,6 +1431,8 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, __u32 bytes_sent; __u16 byte_count; + *nbytes = 0; + /* cFYI(1, ("write at %lld %d bytes", offset, count));*/ if (tcon->ses == NULL) return -ECONNABORTED; @@ -1512,11 +1515,18 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, cifs_stats_inc(&tcon->num_writes); if (rc) { cFYI(1, ("Send error in write = %d", rc)); - *nbytes = 0; } else { *nbytes = le16_to_cpu(pSMBr->CountHigh); *nbytes = (*nbytes) << 16; *nbytes += le16_to_cpu(pSMBr->Count); + + /* + * Mask off high 16 bits when bytes written as returned by the + * server is greater than bytes requested by the client. Some + * OS/2 servers are known to set incorrect CountHigh values. + */ + if (*nbytes > count) + *nbytes &= 0xFFFF; } cifs_buf_release(pSMB); @@ -1605,6 +1615,14 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, *nbytes = le16_to_cpu(pSMBr->CountHigh); *nbytes = (*nbytes) << 16; *nbytes += le16_to_cpu(pSMBr->Count); + + /* + * Mask off high 16 bits when bytes written as returned by the + * server is greater than bytes requested by the client. OS/2 + * servers are known to set incorrect CountHigh values. + */ + if (*nbytes > count) + *nbytes &= 0xFFFF; } /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ @@ -1793,8 +1811,21 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, } parm_data = (struct cifs_posix_lock *) ((char *)&pSMBr->hdr.Protocol + data_offset); - if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK)) + if (parm_data->lock_type == __constant_cpu_to_le16(CIFS_UNLCK)) pLockData->fl_type = F_UNLCK; + else { + if (parm_data->lock_type == + __constant_cpu_to_le16(CIFS_RDLCK)) + pLockData->fl_type = F_RDLCK; + else if (parm_data->lock_type == + __constant_cpu_to_le16(CIFS_WRLCK)) + pLockData->fl_type = F_WRLCK; + + pLockData->fl_start = parm_data->start; + pLockData->fl_end = parm_data->start + + parm_data->length - 1; + pLockData->fl_pid = parm_data->pid; + } } plk_err_exit: diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 45eb6cba793..d9566bf8f91 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -23,6 +23,7 @@ #include <linux/string.h> #include <linux/list.h> #include <linux/wait.h> +#include <linux/slab.h> #include <linux/pagemap.h> #include <linux/ctype.h> #include <linux/utsname.h> diff --git a/fs/cifs/dns_resolve.c b/fs/cifs/dns_resolve.c index 87948147d7e..6f8a0e3fb25 100644 --- a/fs/cifs/dns_resolve.c +++ b/fs/cifs/dns_resolve.c @@ -23,6 +23,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include <linux/slab.h> #include <keys/user-type.h> #include "dns_resolve.h" #include "cifsglob.h" diff --git a/fs/cifs/file.c b/fs/cifs/file.c index ca2ba7a0193..9b11a8f56f3 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -31,6 +31,7 @@ #include <linux/task_io_accounting_ops.h> #include <linux/delay.h> #include <linux/mount.h> +#include <linux/slab.h> #include <asm/div64.h> #include "cifsfs.h" #include "cifspdu.h" @@ -838,8 +839,32 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) } else { /* if rc == ERR_SHARING_VIOLATION ? */ - rc = 0; /* do not change lock type to unlock - since range in use */ + rc = 0; + + if (lockType & LOCKING_ANDX_SHARED_LOCK) { + pfLock->fl_type = F_WRLCK; + } else { + rc = CIFSSMBLock(xid, tcon, netfid, length, + pfLock->fl_start, 0, 1, + lockType | LOCKING_ANDX_SHARED_LOCK, + 0 /* wait flag */); + if (rc == 0) { + rc = CIFSSMBLock(xid, tcon, netfid, + length, pfLock->fl_start, 1, 0, + lockType | + LOCKING_ANDX_SHARED_LOCK, + 0 /* wait flag */); + pfLock->fl_type = F_RDLCK; + if (rc != 0) + cERROR(1, ("Error unlocking " + "previously locked range %d " + "during test of lock", rc)); + rc = 0; + } else { + pfLock->fl_type = F_WRLCK; + rc = 0; + } + } } FreeXid(xid); diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 723daaccbd0..35ec1171621 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -20,6 +20,7 @@ */ #include <linux/fs.h> #include <linux/stat.h> +#include <linux/slab.h> #include <linux/pagemap.h> #include <asm/div64.h> #include "cifsfs.h" diff --git a/fs/cifs/link.c b/fs/cifs/link.c index fc1e0487eae..c1a9d4236a8 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c @@ -20,6 +20,7 @@ */ #include <linux/fs.h> #include <linux/stat.h> +#include <linux/slab.h> #include <linux/namei.h> #include "cifsfs.h" #include "cifspdu.h" diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index c343b14ba2d..18e0bc1fb59 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c @@ -22,6 +22,7 @@ */ #include <linux/fs.h> #include <linux/pagemap.h> +#include <linux/slab.h> #include <linux/stat.h> #include "cifspdu.h" #include "cifsglob.h" diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index aaa9c1c5a5b..7c3fd7463f4 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c @@ -29,6 +29,7 @@ #include "ntlmssp.h" #include "nterr.h" #include <linux/utsname.h> +#include <linux/slab.h> #include "cifs_spnego.h" extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c index 93fb09a99c6..192ea51af20 100644 --- a/fs/cifs/smbencrypt.c +++ b/fs/cifs/smbencrypt.c @@ -24,6 +24,7 @@ */ #include <linux/module.h> +#include <linux/slab.h> #include <linux/fs.h> #include <linux/string.h> #include <linux/kernel.h> diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 07b8e71544e..ad081fe7eb1 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -22,6 +22,7 @@ #include <linux/fs.h> #include <linux/list.h> +#include <linux/gfp.h> #include <linux/wait.h> #include <linux/net.h> #include <linux/delay.h> diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index 3e2ef0de120..f555ce077d4 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c @@ -21,6 +21,7 @@ #include <linux/fs.h> #include <linux/posix_acl_xattr.h> +#include <linux/slab.h> #include "cifsfs.h" #include "cifspdu.h" #include "cifsglob.h" |