Commit 7c5e8691 authored by Konstantin Baev's avatar Konstantin Baev

Update sources 2.6.27 - 2.6.28

- Send SMB flush in cifsf_sync (Backport from CIFS devel git) - Remove oplock part of Etersoft patches
parent c96ca272
...@@ -340,6 +340,8 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v) ...@@ -340,6 +340,8 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v)
seq_printf(m, "\nWrites: %d Bytes: %lld", seq_printf(m, "\nWrites: %d Bytes: %lld",
atomic_read(&tcon->num_writes), atomic_read(&tcon->num_writes),
(long long)(tcon->bytes_written)); (long long)(tcon->bytes_written));
seq_printf(m, "\nFlushes: %d",
atomic_read(&tcon->num_flushes));
seq_printf(m, "\nLocks: %d HardLinks: %d " seq_printf(m, "\nLocks: %d HardLinks: %d "
"Symlinks: %d", "Symlinks: %d",
atomic_read(&tcon->num_locks), atomic_read(&tcon->num_locks),
......
...@@ -600,19 +600,6 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -600,19 +600,6 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
return written; return written;
} }
static ssize_t cifs_file_read(struct file *file, char *user, size_t cnt, loff_t *pos)
{
if( file!=NULL && file->f_dentry!=NULL && CIFS_I(file->f_dentry->d_inode)!=NULL ) {
int retval = 0;
CIFS_I(file->f_dentry->d_inode)->needForceInvalidate = 1;
retval = cifs_revalidate(file->f_dentry);
if( retval < 0 )
return (ssize_t)retval;
}
return do_sync_read(file,user,cnt,pos);
}
static loff_t cifs_llseek(struct file *file, loff_t offset, int origin) static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
{ {
/* origin == SEEK_END => we must revalidate the cached file length */ /* origin == SEEK_END => we must revalidate the cached file length */
...@@ -691,7 +678,7 @@ const struct inode_operations cifs_symlink_inode_ops = { ...@@ -691,7 +678,7 @@ const struct inode_operations cifs_symlink_inode_ops = {
}; };
const struct file_operations cifs_file_ops = { const struct file_operations cifs_file_ops = {
.read = cifs_file_read, .read = do_sync_read,
.write = do_sync_write, .write = do_sync_write,
.aio_read = generic_file_aio_read, .aio_read = generic_file_aio_read,
.aio_write = cifs_file_aio_write, .aio_write = cifs_file_aio_write,
......
...@@ -246,6 +246,7 @@ struct cifsTconInfo { ...@@ -246,6 +246,7 @@ struct cifsTconInfo {
atomic_t num_smbs_sent; atomic_t num_smbs_sent;
atomic_t num_writes; atomic_t num_writes;
atomic_t num_reads; atomic_t num_reads;
atomic_t num_flushes;
atomic_t num_oplock_brks; atomic_t num_oplock_brks;
atomic_t num_opens; atomic_t num_opens;
atomic_t num_closes; atomic_t num_closes;
...@@ -358,7 +359,6 @@ struct cifsInodeInfo { ...@@ -358,7 +359,6 @@ struct cifsInodeInfo {
bool clientCanCacheRead:1; /* read oplock */ bool clientCanCacheRead:1; /* read oplock */
bool clientCanCacheAll:1; /* read and writebehind oplock */ bool clientCanCacheAll:1; /* read and writebehind oplock */
bool oplockPending:1; bool oplockPending:1;
unsigned needForceInvalidate:1;
struct inode vfs_inode; struct inode vfs_inode;
}; };
......
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#define SMB_COM_CREATE_DIRECTORY 0x00 /* trivial response */ #define SMB_COM_CREATE_DIRECTORY 0x00 /* trivial response */
#define SMB_COM_DELETE_DIRECTORY 0x01 /* trivial response */ #define SMB_COM_DELETE_DIRECTORY 0x01 /* trivial response */
#define SMB_COM_CLOSE 0x04 /* triv req/rsp, timestamp ignored */ #define SMB_COM_CLOSE 0x04 /* triv req/rsp, timestamp ignored */
#define SMB_COM_FLUSH 0x05 /* triv req/rsp */
#define SMB_COM_DELETE 0x06 /* trivial response */ #define SMB_COM_DELETE 0x06 /* trivial response */
#define SMB_COM_RENAME 0x07 /* trivial response */ #define SMB_COM_RENAME 0x07 /* trivial response */
#define SMB_COM_QUERY_INFORMATION 0x08 /* aka getattr */ #define SMB_COM_QUERY_INFORMATION 0x08 /* aka getattr */
...@@ -798,6 +799,12 @@ typedef struct smb_com_close_rsp { ...@@ -798,6 +799,12 @@ typedef struct smb_com_close_rsp {
__u16 ByteCount; /* bct = 0 */ __u16 ByteCount; /* bct = 0 */
} __attribute__((packed)) CLOSE_RSP; } __attribute__((packed)) CLOSE_RSP;
typedef struct smb_com_flush_req {
struct smb_hdr hdr; /* wct = 1 */
__u16 FileID;
__u16 ByteCount; /* 0 */
} __attribute__((packed)) FLUSH_REQ;
typedef struct smb_com_findclose_req { typedef struct smb_com_findclose_req {
struct smb_hdr hdr; /* wct = 1 */ struct smb_hdr hdr; /* wct = 1 */
__u16 FileID; __u16 FileID;
......
...@@ -275,6 +275,9 @@ extern int CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, ...@@ -275,6 +275,9 @@ extern int CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon,
extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon,
const int smb_file_id); const int smb_file_id);
extern int CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon,
const int smb_file_id);
extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
const int netfid, unsigned int count, const int netfid, unsigned int count,
const __u64 lseek, unsigned int *nbytes, char **buf, const __u64 lseek, unsigned int *nbytes, char **buf,
......
...@@ -1931,6 +1931,27 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id) ...@@ -1931,6 +1931,27 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
} }
int int
CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
{
int rc = 0;
FLUSH_REQ *pSMB = NULL;
cFYI(1, ("In CIFSSMBFlush"));
rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
if (rc)
return rc;
pSMB->FileID = (__u16) smb_file_id;
pSMB->ByteCount = 0;
rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
cifs_stats_inc(&tcon->num_flushes);
if (rc)
cERROR(1, ("Send error in Flush = %d", rc));
return rc;
}
int
CIFSSMBRename(const int xid, struct cifsTconInfo *tcon, CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
const char *fromName, const char *toName, const char *fromName, const char *toName,
const struct nls_table *nls_codepage, int remap) const struct nls_table *nls_codepage, int remap)
......
...@@ -1511,6 +1511,9 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync) ...@@ -1511,6 +1511,9 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
{ {
int xid; int xid;
int rc = 0; int rc = 0;
struct cifsTconInfo *tcon;
struct cifsFileInfo *smbfile =
(struct cifsFileInfo *)file->private_data;
struct inode *inode = file->f_path.dentry->d_inode; struct inode *inode = file->f_path.dentry->d_inode;
xid = GetXid(); xid = GetXid();
...@@ -1522,7 +1525,11 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync) ...@@ -1522,7 +1525,11 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
if (rc == 0) { if (rc == 0) {
rc = CIFS_I(inode)->write_behind_rc; rc = CIFS_I(inode)->write_behind_rc;
CIFS_I(inode)->write_behind_rc = 0; CIFS_I(inode)->write_behind_rc = 0;
tcon = CIFS_SB(inode->i_sb)->tcon;
if (!rc && tcon && smbfile)
rc = CIFSSMBFlush(xid, tcon, smbfile->netfid);
} }
FreeXid(xid); FreeXid(xid);
return rc; return rc;
} }
......
...@@ -1252,7 +1252,7 @@ int cifs_revalidate(struct dentry *direntry) ...@@ -1252,7 +1252,7 @@ int cifs_revalidate(struct dentry *direntry)
direntry->d_inode->i_count.counter, direntry, direntry->d_inode->i_count.counter, direntry,
direntry->d_time, jiffies)); direntry->d_time, jiffies));
if (cifsInode->time == 0 || cifsInode->needForceInvalidate ) { if (cifsInode->time == 0) {
/* was set to zero previously to force revalidate */ /* was set to zero previously to force revalidate */
} else if (time_before(jiffies, cifsInode->time + HZ) && } else if (time_before(jiffies, cifsInode->time + HZ) &&
lookupCacheEnabled) { lookupCacheEnabled) {
...@@ -1294,10 +1294,9 @@ int cifs_revalidate(struct dentry *direntry) ...@@ -1294,10 +1294,9 @@ int cifs_revalidate(struct dentry *direntry)
/* if not oplocked, we invalidate inode pages if mtime or file size /* if not oplocked, we invalidate inode pages if mtime or file size
had changed on server */ had changed on server */
if (!cifsInode->needForceInvalidate && if (timespec_equal(&local_mtime, &direntry->d_inode->i_mtime) &&
timespec_equal(&local_mtime,&direntry->d_inode->i_mtime) && (local_size == direntry->d_inode->i_size)) {
(local_size == direntry->d_inode->i_size) ) { cFYI(1, ("cifs_revalidate - inode unchanged"));
cFYI(1, ("************** cifs_revalidate - inode unchanged"));
} else { } else {
/* file may have changed on server */ /* file may have changed on server */
if (cifsInode->clientCanCacheRead) { if (cifsInode->clientCanCacheRead) {
...@@ -1330,15 +1329,11 @@ int cifs_revalidate(struct dentry *direntry) ...@@ -1330,15 +1329,11 @@ int cifs_revalidate(struct dentry *direntry)
if (direntry->d_inode->i_mapping) { if (direntry->d_inode->i_mapping) {
wbrc = filemap_fdatawait(direntry->d_inode->i_mapping); wbrc = filemap_fdatawait(direntry->d_inode->i_mapping);
if( cifsInode->needForceInvalidate ) {
cFYI(1, ("Force invalidating."));
invalidate_remote_inode(direntry->d_inode);
cifsInode->needForceInvalidate = 0;
if (wbrc) if (wbrc)
CIFS_I(direntry->d_inode)->write_behind_rc = wbrc; CIFS_I(direntry->d_inode)->write_behind_rc = wbrc;
} }
/* may eventually have to do this for open files too */ /* may eventually have to do this for open files too */
} else if (list_empty(&(cifsInode->openFileList))) { if (list_empty(&(cifsInode->openFileList))) {
/* changed on server - flush read ahead pages */ /* changed on server - flush read ahead pages */
cFYI(1, ("Invalidating read ahead data on " cFYI(1, ("Invalidating read ahead data on "
"closed file")); "closed file"));
......
...@@ -340,6 +340,8 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v) ...@@ -340,6 +340,8 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v)
seq_printf(m, "\nWrites: %d Bytes: %lld", seq_printf(m, "\nWrites: %d Bytes: %lld",
atomic_read(&tcon->num_writes), atomic_read(&tcon->num_writes),
(long long)(tcon->bytes_written)); (long long)(tcon->bytes_written));
seq_printf(m, "\nFlushes: %d",
atomic_read(&tcon->num_flushes));
seq_printf(m, "\nLocks: %d HardLinks: %d " seq_printf(m, "\nLocks: %d HardLinks: %d "
"Symlinks: %d", "Symlinks: %d",
atomic_read(&tcon->num_locks), atomic_read(&tcon->num_locks),
......
...@@ -604,19 +604,6 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -604,19 +604,6 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
return written; return written;
} }
static ssize_t cifs_file_read(struct file *file, char *user, size_t cnt, loff_t *pos)
{
if( file!=NULL && file->f_dentry!=NULL && CIFS_I(file->f_dentry->d_inode)!=NULL ) {
int retval = 0;
CIFS_I(file->f_dentry->d_inode)->needForceInvalidate = 1;
retval = cifs_revalidate(file->f_dentry);
if( retval < 0 )
return (ssize_t)retval;
}
return do_sync_read(file,user,cnt,pos);
}
static loff_t cifs_llseek(struct file *file, loff_t offset, int origin) static loff_t cifs_llseek(struct file *file, loff_t offset, int origin)
{ {
/* origin == SEEK_END => we must revalidate the cached file length */ /* origin == SEEK_END => we must revalidate the cached file length */
...@@ -726,7 +713,7 @@ const struct inode_operations cifs_symlink_inode_ops = { ...@@ -726,7 +713,7 @@ const struct inode_operations cifs_symlink_inode_ops = {
}; };
const struct file_operations cifs_file_ops = { const struct file_operations cifs_file_ops = {
.read = cifs_file_read, .read = do_sync_read,
.write = do_sync_write, .write = do_sync_write,
.aio_read = generic_file_aio_read, .aio_read = generic_file_aio_read,
.aio_write = cifs_file_aio_write, .aio_write = cifs_file_aio_write,
......
...@@ -246,6 +246,7 @@ struct cifsTconInfo { ...@@ -246,6 +246,7 @@ struct cifsTconInfo {
atomic_t num_smbs_sent; atomic_t num_smbs_sent;
atomic_t num_writes; atomic_t num_writes;
atomic_t num_reads; atomic_t num_reads;
atomic_t num_flushes;
atomic_t num_oplock_brks; atomic_t num_oplock_brks;
atomic_t num_opens; atomic_t num_opens;
atomic_t num_closes; atomic_t num_closes;
...@@ -359,7 +360,6 @@ struct cifsInodeInfo { ...@@ -359,7 +360,6 @@ struct cifsInodeInfo {
bool clientCanCacheRead:1; /* read oplock */ bool clientCanCacheRead:1; /* read oplock */
bool clientCanCacheAll:1; /* read and writebehind oplock */ bool clientCanCacheAll:1; /* read and writebehind oplock */
bool oplockPending:1; bool oplockPending:1;
unsigned needForceInvalidate:1;
bool delete_pending:1; /* DELETE_ON_CLOSE is set */ bool delete_pending:1; /* DELETE_ON_CLOSE is set */
struct inode vfs_inode; struct inode vfs_inode;
}; };
......
...@@ -51,6 +51,7 @@ ...@@ -51,6 +51,7 @@
#define SMB_COM_CREATE_DIRECTORY 0x00 /* trivial response */ #define SMB_COM_CREATE_DIRECTORY 0x00 /* trivial response */
#define SMB_COM_DELETE_DIRECTORY 0x01 /* trivial response */ #define SMB_COM_DELETE_DIRECTORY 0x01 /* trivial response */
#define SMB_COM_CLOSE 0x04 /* triv req/rsp, timestamp ignored */ #define SMB_COM_CLOSE 0x04 /* triv req/rsp, timestamp ignored */
#define SMB_COM_FLUSH 0x05 /* triv req/rsp */
#define SMB_COM_DELETE 0x06 /* trivial response */ #define SMB_COM_DELETE 0x06 /* trivial response */
#define SMB_COM_RENAME 0x07 /* trivial response */ #define SMB_COM_RENAME 0x07 /* trivial response */
#define SMB_COM_QUERY_INFORMATION 0x08 /* aka getattr */ #define SMB_COM_QUERY_INFORMATION 0x08 /* aka getattr */
...@@ -798,6 +799,12 @@ typedef struct smb_com_close_rsp { ...@@ -798,6 +799,12 @@ typedef struct smb_com_close_rsp {
__u16 ByteCount; /* bct = 0 */ __u16 ByteCount; /* bct = 0 */
} __attribute__((packed)) CLOSE_RSP; } __attribute__((packed)) CLOSE_RSP;
typedef struct smb_com_flush_req {
struct smb_hdr hdr; /* wct = 1 */
__u16 FileID;
__u16 ByteCount; /* 0 */
} __attribute__((packed)) FLUSH_REQ;
typedef struct smb_com_findclose_req { typedef struct smb_com_findclose_req {
struct smb_hdr hdr; /* wct = 1 */ struct smb_hdr hdr; /* wct = 1 */
__u16 FileID; __u16 FileID;
......
...@@ -277,6 +277,9 @@ extern int CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon, ...@@ -277,6 +277,9 @@ extern int CIFSPOSIXCreate(const int xid, struct cifsTconInfo *tcon,
extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon,
const int smb_file_id); const int smb_file_id);
extern int CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon,
const int smb_file_id);
extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
const int netfid, unsigned int count, const int netfid, unsigned int count,
const __u64 lseek, unsigned int *nbytes, char **buf, const __u64 lseek, unsigned int *nbytes, char **buf,
......
...@@ -1933,6 +1933,27 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id) ...@@ -1933,6 +1933,27 @@ CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
} }
int int
CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon, int smb_file_id)
{
int rc = 0;
FLUSH_REQ *pSMB = NULL;
cFYI(1, ("In CIFSSMBFlush"));
rc = small_smb_init(SMB_COM_FLUSH, 1, tcon, (void **) &pSMB);
if (rc)
return rc;
pSMB->FileID = (__u16) smb_file_id;
pSMB->ByteCount = 0;
rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
cifs_stats_inc(&tcon->num_flushes);
if (rc)
cERROR(1, ("Send error in Flush = %d", rc));
return rc;
}
int
CIFSSMBRename(const int xid, struct cifsTconInfo *tcon, CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
const char *fromName, const char *toName, const char *fromName, const char *toName,
const struct nls_table *nls_codepage, int remap) const struct nls_table *nls_codepage, int remap)
......
...@@ -1533,6 +1533,9 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync) ...@@ -1533,6 +1533,9 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
{ {
int xid; int xid;
int rc = 0; int rc = 0;
struct cifsTconInfo *tcon;
struct cifsFileInfo *smbfile =
(struct cifsFileInfo *)file->private_data;
struct inode *inode = file->f_path.dentry->d_inode; struct inode *inode = file->f_path.dentry->d_inode;
xid = GetXid(); xid = GetXid();
...@@ -1544,7 +1547,11 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync) ...@@ -1544,7 +1547,11 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
if (rc == 0) { if (rc == 0) {
rc = CIFS_I(inode)->write_behind_rc; rc = CIFS_I(inode)->write_behind_rc;
CIFS_I(inode)->write_behind_rc = 0; CIFS_I(inode)->write_behind_rc = 0;
tcon = CIFS_SB(inode->i_sb)->tcon;
if (!rc && tcon && smbfile)
rc = CIFSSMBFlush(xid, tcon, smbfile->netfid);
} }
FreeXid(xid); FreeXid(xid);
return rc; return rc;
} }
......
...@@ -1426,7 +1426,7 @@ int cifs_revalidate(struct dentry *direntry) ...@@ -1426,7 +1426,7 @@ int cifs_revalidate(struct dentry *direntry)
direntry->d_inode->i_count.counter, direntry, direntry->d_inode->i_count.counter, direntry,
direntry->d_time, jiffies)); direntry->d_time, jiffies));
if (cifsInode->time == 0 || cifsInode->needForceInvalidate ) { if (cifsInode->time == 0) {
/* was set to zero previously to force revalidate */ /* was set to zero previously to force revalidate */
} else if (time_before(jiffies, cifsInode->time + HZ) && } else if (time_before(jiffies, cifsInode->time + HZ) &&
lookupCacheEnabled) { lookupCacheEnabled) {
...@@ -1468,10 +1468,9 @@ int cifs_revalidate(struct dentry *direntry) ...@@ -1468,10 +1468,9 @@ int cifs_revalidate(struct dentry *direntry)
/* if not oplocked, we invalidate inode pages if mtime or file size /* if not oplocked, we invalidate inode pages if mtime or file size
had changed on server */ had changed on server */
if (!cifsInode->needForceInvalidate && if (timespec_equal(&local_mtime, &direntry->d_inode->i_mtime) &&
timespec_equal(&local_mtime,&direntry->d_inode->i_mtime) && (local_size == direntry->d_inode->i_size)) {
(local_size == direntry->d_inode->i_size) ) { cFYI(1, ("cifs_revalidate - inode unchanged"));
cFYI(1, ("************** cifs_revalidate - inode unchanged"));
} else { } else {
/* file may have changed on server */ /* file may have changed on server */
if (cifsInode->clientCanCacheRead) { if (cifsInode->clientCanCacheRead) {
...@@ -1504,15 +1503,11 @@ int cifs_revalidate(struct dentry *direntry) ...@@ -1504,15 +1503,11 @@ int cifs_revalidate(struct dentry *direntry)
if (direntry->d_inode->i_mapping) { if (direntry->d_inode->i_mapping) {
wbrc = filemap_fdatawait(direntry->d_inode->i_mapping); wbrc = filemap_fdatawait(direntry->d_inode->i_mapping);
if( cifsInode->needForceInvalidate ) {
cFYI(1, ("Force invalidating."));
invalidate_remote_inode(direntry->d_inode);
cifsInode->needForceInvalidate = 0;
if (wbrc) if (wbrc)
CIFS_I(direntry->d_inode)->write_behind_rc = wbrc; CIFS_I(direntry->d_inode)->write_behind_rc = wbrc;
} }
/* may eventually have to do this for open files too */ /* may eventually have to do this for open files too */
} else if (list_empty(&(cifsInode->openFileList))) { if (list_empty(&(cifsInode->openFileList))) {
/* changed on server - flush read ahead pages */ /* changed on server - flush read ahead pages */
cFYI(1, ("Invalidating read ahead data on " cFYI(1, ("Invalidating read ahead data on "
"closed file")); "closed file"));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment