aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/cifs_fs_sb.h3
-rw-r--r--fs/cifs/cifsfs.c11
-rw-r--r--fs/cifs/cifssmb.c34
-rw-r--r--fs/cifs/file.c28
4 files changed, 72 insertions, 4 deletions
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 4797787c6a44..246a167cb913 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -18,6 +18,8 @@
18#ifndef _CIFS_FS_SB_H 18#ifndef _CIFS_FS_SB_H
19#define _CIFS_FS_SB_H 19#define _CIFS_FS_SB_H
20 20
21#include <linux/backing-dev.h>
22
21#define CIFS_MOUNT_NO_PERM 1 /* do not do client vfs_perm check */ 23#define CIFS_MOUNT_NO_PERM 1 /* do not do client vfs_perm check */
22#define CIFS_MOUNT_SET_UID 2 /* set current's euid in create etc. */ 24#define CIFS_MOUNT_SET_UID 2 /* set current's euid in create etc. */
23#define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */ 25#define CIFS_MOUNT_SERVER_INUM 4 /* inode numbers from uniqueid from server */
@@ -50,5 +52,6 @@ struct cifs_sb_info {
50#ifdef CONFIG_CIFS_DFS_UPCALL 52#ifdef CONFIG_CIFS_DFS_UPCALL
51 char *mountdata; /* mount options received at mount time */ 53 char *mountdata; /* mount options received at mount time */
52#endif 54#endif
55 struct backing_dev_info bdi;
53}; 56};
54#endif /* _CIFS_FS_SB_H */ 57#endif /* _CIFS_FS_SB_H */
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 5183bc2a1916..ad235d604a0b 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -103,6 +103,12 @@ cifs_read_super(struct super_block *sb, void *data,
103 if (cifs_sb == NULL) 103 if (cifs_sb == NULL)
104 return -ENOMEM; 104 return -ENOMEM;
105 105
106 rc = bdi_setup_and_register(&cifs_sb->bdi, "cifs", BDI_CAP_MAP_COPY);
107 if (rc) {
108 kfree(cifs_sb);
109 return rc;
110 }
111
106#ifdef CONFIG_CIFS_DFS_UPCALL 112#ifdef CONFIG_CIFS_DFS_UPCALL
107 /* copy mount params to sb for use in submounts */ 113 /* copy mount params to sb for use in submounts */
108 /* BB: should we move this after the mount so we 114 /* BB: should we move this after the mount so we
@@ -115,6 +121,7 @@ cifs_read_super(struct super_block *sb, void *data,
115 int len = strlen(data); 121 int len = strlen(data);
116 cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL); 122 cifs_sb->mountdata = kzalloc(len + 1, GFP_KERNEL);
117 if (cifs_sb->mountdata == NULL) { 123 if (cifs_sb->mountdata == NULL) {
124 bdi_destroy(&cifs_sb->bdi);
118 kfree(sb->s_fs_info); 125 kfree(sb->s_fs_info);
119 sb->s_fs_info = NULL; 126 sb->s_fs_info = NULL;
120 return -ENOMEM; 127 return -ENOMEM;
@@ -135,6 +142,7 @@ cifs_read_super(struct super_block *sb, void *data,
135 142
136 sb->s_magic = CIFS_MAGIC_NUMBER; 143 sb->s_magic = CIFS_MAGIC_NUMBER;
137 sb->s_op = &cifs_super_ops; 144 sb->s_op = &cifs_super_ops;
145 sb->s_bdi = &cifs_sb->bdi;
138/* if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512) 146/* if (cifs_sb->tcon->ses->server->maxBuf > MAX_CIFS_HDR_SIZE + 512)
139 sb->s_blocksize = 147 sb->s_blocksize =
140 cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */ 148 cifs_sb->tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE; */
@@ -183,6 +191,7 @@ out_mount_failed:
183 } 191 }
184#endif 192#endif
185 unload_nls(cifs_sb->local_nls); 193 unload_nls(cifs_sb->local_nls);
194 bdi_destroy(&cifs_sb->bdi);
186 kfree(cifs_sb); 195 kfree(cifs_sb);
187 } 196 }
188 return rc; 197 return rc;
@@ -214,6 +223,7 @@ cifs_put_super(struct super_block *sb)
214#endif 223#endif
215 224
216 unload_nls(cifs_sb->local_nls); 225 unload_nls(cifs_sb->local_nls);
226 bdi_destroy(&cifs_sb->bdi);
217 kfree(cifs_sb); 227 kfree(cifs_sb);
218 228
219 unlock_kernel(); 229 unlock_kernel();
@@ -808,6 +818,7 @@ const struct file_operations cifs_file_direct_nobrl_ops = {
808 .release = cifs_close, 818 .release = cifs_close,
809 .fsync = cifs_fsync, 819 .fsync = cifs_fsync,
810 .flush = cifs_flush, 820 .flush = cifs_flush,
821 .mmap = cifs_file_mmap,
811 .splice_read = generic_file_splice_read, 822 .splice_read = generic_file_splice_read,
812#ifdef CONFIG_CIFS_POSIX 823#ifdef CONFIG_CIFS_POSIX
813 .unlocked_ioctl = cifs_ioctl, 824 .unlocked_ioctl = cifs_ioctl,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 3f4fbd670507..5d3f29fef532 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -1431,6 +1431,8 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
1431 __u32 bytes_sent; 1431 __u32 bytes_sent;
1432 __u16 byte_count; 1432 __u16 byte_count;
1433 1433
1434 *nbytes = 0;
1435
1434 /* cFYI(1, ("write at %lld %d bytes", offset, count));*/ 1436 /* cFYI(1, ("write at %lld %d bytes", offset, count));*/
1435 if (tcon->ses == NULL) 1437 if (tcon->ses == NULL)
1436 return -ECONNABORTED; 1438 return -ECONNABORTED;
@@ -1513,11 +1515,18 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
1513 cifs_stats_inc(&tcon->num_writes); 1515 cifs_stats_inc(&tcon->num_writes);
1514 if (rc) { 1516 if (rc) {
1515 cFYI(1, ("Send error in write = %d", rc)); 1517 cFYI(1, ("Send error in write = %d", rc));
1516 *nbytes = 0;
1517 } else { 1518 } else {
1518 *nbytes = le16_to_cpu(pSMBr->CountHigh); 1519 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1519 *nbytes = (*nbytes) << 16; 1520 *nbytes = (*nbytes) << 16;
1520 *nbytes += le16_to_cpu(pSMBr->Count); 1521 *nbytes += le16_to_cpu(pSMBr->Count);
1522
1523 /*
1524 * Mask off high 16 bits when bytes written as returned by the
1525 * server is greater than bytes requested by the client. Some
1526 * OS/2 servers are known to set incorrect CountHigh values.
1527 */
1528 if (*nbytes > count)
1529 *nbytes &= 0xFFFF;
1521 } 1530 }
1522 1531
1523 cifs_buf_release(pSMB); 1532 cifs_buf_release(pSMB);
@@ -1606,6 +1615,14 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
1606 *nbytes = le16_to_cpu(pSMBr->CountHigh); 1615 *nbytes = le16_to_cpu(pSMBr->CountHigh);
1607 *nbytes = (*nbytes) << 16; 1616 *nbytes = (*nbytes) << 16;
1608 *nbytes += le16_to_cpu(pSMBr->Count); 1617 *nbytes += le16_to_cpu(pSMBr->Count);
1618
1619 /*
1620 * Mask off high 16 bits when bytes written as returned by the
1621 * server is greater than bytes requested by the client. OS/2
1622 * servers are known to set incorrect CountHigh values.
1623 */
1624 if (*nbytes > count)
1625 *nbytes &= 0xFFFF;
1609 } 1626 }
1610 1627
1611/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ 1628/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
@@ -1794,8 +1811,21 @@ CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
1794 } 1811 }
1795 parm_data = (struct cifs_posix_lock *) 1812 parm_data = (struct cifs_posix_lock *)
1796 ((char *)&pSMBr->hdr.Protocol + data_offset); 1813 ((char *)&pSMBr->hdr.Protocol + data_offset);
1797 if (parm_data->lock_type == cpu_to_le16(CIFS_UNLCK)) 1814 if (parm_data->lock_type == __constant_cpu_to_le16(CIFS_UNLCK))
1798 pLockData->fl_type = F_UNLCK; 1815 pLockData->fl_type = F_UNLCK;
1816 else {
1817 if (parm_data->lock_type ==
1818 __constant_cpu_to_le16(CIFS_RDLCK))
1819 pLockData->fl_type = F_RDLCK;
1820 else if (parm_data->lock_type ==
1821 __constant_cpu_to_le16(CIFS_WRLCK))
1822 pLockData->fl_type = F_WRLCK;
1823
1824 pLockData->fl_start = parm_data->start;
1825 pLockData->fl_end = parm_data->start +
1826 parm_data->length - 1;
1827 pLockData->fl_pid = parm_data->pid;
1828 }
1799 } 1829 }
1800 1830
1801plk_err_exit: 1831plk_err_exit:
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 058b390d3da8..9b11a8f56f3a 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -839,8 +839,32 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
839 839
840 } else { 840 } else {
841 /* if rc == ERR_SHARING_VIOLATION ? */ 841 /* if rc == ERR_SHARING_VIOLATION ? */
842 rc = 0; /* do not change lock type to unlock 842 rc = 0;
843 since range in use */ 843
844 if (lockType & LOCKING_ANDX_SHARED_LOCK) {
845 pfLock->fl_type = F_WRLCK;
846 } else {
847 rc = CIFSSMBLock(xid, tcon, netfid, length,
848 pfLock->fl_start, 0, 1,
849 lockType | LOCKING_ANDX_SHARED_LOCK,
850 0 /* wait flag */);
851 if (rc == 0) {
852 rc = CIFSSMBLock(xid, tcon, netfid,
853 length, pfLock->fl_start, 1, 0,
854 lockType |
855 LOCKING_ANDX_SHARED_LOCK,
856 0 /* wait flag */);
857 pfLock->fl_type = F_RDLCK;
858 if (rc != 0)
859 cERROR(1, ("Error unlocking "
860 "previously locked range %d "
861 "during test of lock", rc));
862 rc = 0;
863 } else {
864 pfLock->fl_type = F_WRLCK;
865 rc = 0;
866 }
867 }
844 } 868 }
845 869
846 FreeXid(xid); 870 FreeXid(xid);