Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
etercifs
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
etersoft
etercifs
Commits
edc2bedb
Commit
edc2bedb
authored
Apr 05, 2011
by
Pavel Shilovsky
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add strict cache mode for 2.6.32
parent
c8cd2ff8
Show whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
561 additions
and
176 deletions
+561
-176
README
sources/2.6.32/README
+5
-0
cifs_fs_sb.h
sources/2.6.32/cifs_fs_sb.h
+1
-0
cifsfs.c
sources/2.6.32/cifsfs.c
+48
-4
cifsfs.h
sources/2.6.32/cifsfs.h
+11
-2
cifsglob.h
sources/2.6.32/cifsglob.h
+1
-0
cifsproto.h
sources/2.6.32/cifsproto.h
+5
-1
connect.c
sources/2.6.32/connect.c
+6
-1
dir.c
sources/2.6.32/dir.c
+9
-15
file.c
sources/2.6.32/file.c
+390
-92
inode.c
sources/2.6.32/inode.c
+61
-56
misc.c
sources/2.6.32/misc.c
+24
-5
No files found.
sources/2.6.32/README
View file @
edc2bedb
...
@@ -433,6 +433,11 @@ A partial list of the supported mount options follows:
...
@@ -433,6 +433,11 @@ A partial list of the supported mount options follows:
if oplock (caching token) is granted and held. Note that
if oplock (caching token) is granted and held. Note that
direct allows write operations larger than page size
direct allows write operations larger than page size
to be sent to the server.
to be sent to the server.
strictcache Use for switching on strict cache mode. In this mode the
client reads from the cache all the time it has Oplock Level II,
otherwise - reads from the server. All written data are stored
in the cache, but if the client doesn't have Exclusive Oplock,
it writes the data to the server.
acl Allow setfacl and getfacl to manage posix ACLs if server
acl Allow setfacl and getfacl to manage posix ACLs if server
supports them. (default)
supports them. (default)
noacl Do not allow setfacl and getfacl calls on this mount
noacl Do not allow setfacl and getfacl calls on this mount
...
...
sources/2.6.32/cifs_fs_sb.h
View file @
edc2bedb
...
@@ -34,6 +34,7 @@
...
@@ -34,6 +34,7 @@
#define CIFS_MOUNT_NOPOSIXBRL 0x2000
/* mandatory not posix byte range lock */
#define CIFS_MOUNT_NOPOSIXBRL 0x2000
/* mandatory not posix byte range lock */
#define CIFS_MOUNT_NOSSYNC 0x4000
/* don't do slow SMBflush on every sync*/
#define CIFS_MOUNT_NOSSYNC 0x4000
/* don't do slow SMBflush on every sync*/
#define CIFS_MOUNT_WINE_MODE 0x8000
/* use pid forwarding for wine apps */
#define CIFS_MOUNT_WINE_MODE 0x8000
/* use pid forwarding for wine apps */
#define CIFS_MOUNT_STRICT_IO 0x10000
/* strict cache mode */
struct
cifs_sb_info
{
struct
cifs_sb_info
{
struct
cifsTconInfo
*
tcon
;
/* primary mount */
struct
cifsTconInfo
*
tcon
;
/* primary mount */
...
...
sources/2.6.32/cifsfs.c
View file @
edc2bedb
...
@@ -309,8 +309,7 @@ cifs_alloc_inode(struct super_block *sb)
...
@@ -309,8 +309,7 @@ cifs_alloc_inode(struct super_block *sb)
/* Until the file is open and we have gotten oplock
/* Until the file is open and we have gotten oplock
info back from the server, can not assume caching of
info back from the server, can not assume caching of
file data or metadata */
file data or metadata */
cifs_inode
->
clientCanCacheRead
=
false
;
cifs_set_oplock_level
(
cifs_inode
,
0
);
cifs_inode
->
clientCanCacheAll
=
false
;
cifs_inode
->
delete_pending
=
false
;
cifs_inode
->
delete_pending
=
false
;
cifs_inode
->
vfs_inode
.
i_blkbits
=
14
;
/* 2**14 = CIFS_MAX_MSGSIZE */
cifs_inode
->
vfs_inode
.
i_blkbits
=
14
;
/* 2**14 = CIFS_MAX_MSGSIZE */
cifs_inode
->
server_eof
=
0
;
cifs_inode
->
server_eof
=
0
;
...
@@ -628,10 +627,17 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
...
@@ -628,10 +627,17 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
{
{
struct
inode
*
inode
=
iocb
->
ki_filp
->
f_path
.
dentry
->
d_inode
;
struct
inode
*
inode
=
iocb
->
ki_filp
->
f_path
.
dentry
->
d_inode
;
ssize_t
written
;
ssize_t
written
;
int
rc
;
written
=
generic_file_aio_write
(
iocb
,
iov
,
nr_segs
,
pos
);
written
=
generic_file_aio_write
(
iocb
,
iov
,
nr_segs
,
pos
);
if
(
!
CIFS_I
(
inode
)
->
clientCanCacheAll
)
filemap_fdatawrite
(
inode
->
i_mapping
);
if
(
CIFS_I
(
inode
)
->
clientCanCacheAll
)
return
written
;
rc
=
filemap_fdatawrite
(
inode
->
i_mapping
);
if
(
rc
)
cFYI
(
1
,
(
"cifs_file_aio_write: %d rc on %p inode"
,
rc
,
inode
));
return
written
;
return
written
;
}
}
...
@@ -765,6 +771,25 @@ const struct file_operations cifs_file_ops = {
...
@@ -765,6 +771,25 @@ const struct file_operations cifs_file_ops = {
#endif
/* CONFIG_CIFS_EXPERIMENTAL */
#endif
/* CONFIG_CIFS_EXPERIMENTAL */
};
};
const
struct
file_operations
cifs_file_strict_ops
=
{
.
read
=
do_sync_read
,
.
write
=
do_sync_write
,
.
aio_read
=
cifs_strict_readv
,
.
aio_write
=
cifs_strict_writev
,
.
open
=
cifs_open
,
.
release
=
cifs_close
,
.
lock
=
cifs_lock
,
.
fsync
=
cifs_strict_fsync
,
.
flush
=
cifs_flush
,
.
mmap
=
cifs_file_strict_mmap
,
.
splice_read
=
generic_file_splice_read
,
.
llseek
=
cifs_llseek
,
#ifdef CONFIG_CIFS_POSIX
.
unlocked_ioctl
=
cifs_ioctl
,
#endif
/* CONFIG_CIFS_POSIX */
.
setlease
=
cifs_setlease
,
};
const
struct
file_operations
cifs_file_direct_ops
=
{
const
struct
file_operations
cifs_file_direct_ops
=
{
/* no aio, no readv -
/* no aio, no readv -
BB reevaluate whether they can be done with directio, no cache */
BB reevaluate whether they can be done with directio, no cache */
...
@@ -785,6 +810,7 @@ const struct file_operations cifs_file_direct_ops = {
...
@@ -785,6 +810,7 @@ const struct file_operations cifs_file_direct_ops = {
.
setlease
=
cifs_setlease
,
.
setlease
=
cifs_setlease
,
#endif
/* CONFIG_CIFS_EXPERIMENTAL */
#endif
/* CONFIG_CIFS_EXPERIMENTAL */
};
};
const
struct
file_operations
cifs_file_nobrl_ops
=
{
const
struct
file_operations
cifs_file_nobrl_ops
=
{
.
read
=
do_sync_read
,
.
read
=
do_sync_read
,
.
write
=
do_sync_write
,
.
write
=
do_sync_write
,
...
@@ -806,6 +832,24 @@ const struct file_operations cifs_file_nobrl_ops = {
...
@@ -806,6 +832,24 @@ const struct file_operations cifs_file_nobrl_ops = {
#endif
/* CONFIG_CIFS_EXPERIMENTAL */
#endif
/* CONFIG_CIFS_EXPERIMENTAL */
};
};
const
struct
file_operations
cifs_file_strict_nobrl_ops
=
{
.
read
=
do_sync_read
,
.
write
=
do_sync_write
,
.
aio_read
=
cifs_strict_readv
,
.
aio_write
=
cifs_strict_writev
,
.
open
=
cifs_open
,
.
release
=
cifs_close
,
.
fsync
=
cifs_strict_fsync
,
.
flush
=
cifs_flush
,
.
mmap
=
cifs_file_strict_mmap
,
.
splice_read
=
generic_file_splice_read
,
.
llseek
=
cifs_llseek
,
#ifdef CONFIG_CIFS_POSIX
.
unlocked_ioctl
=
cifs_ioctl
,
#endif
/* CONFIG_CIFS_POSIX */
.
setlease
=
cifs_setlease
,
};
const
struct
file_operations
cifs_file_direct_nobrl_ops
=
{
const
struct
file_operations
cifs_file_direct_nobrl_ops
=
{
/* no aio, no readv -
/* no aio, no readv -
BB reevaluate whether they can be done with directio, no cache */
BB reevaluate whether they can be done with directio, no cache */
...
...
sources/2.6.32/cifsfs.h
View file @
edc2bedb
...
@@ -62,6 +62,7 @@ extern int cifs_rmdir(struct inode *, struct dentry *);
...
@@ -62,6 +62,7 @@ extern int cifs_rmdir(struct inode *, struct dentry *);
extern
int
cifs_rename
(
struct
inode
*
,
struct
dentry
*
,
struct
inode
*
,
extern
int
cifs_rename
(
struct
inode
*
,
struct
dentry
*
,
struct
inode
*
,
struct
dentry
*
);
struct
dentry
*
);
extern
int
cifs_revalidate
(
struct
dentry
*
);
extern
int
cifs_revalidate
(
struct
dentry
*
);
extern
void
cifs_invalidate_mapping
(
struct
inode
*
inode
);
extern
int
cifs_getattr
(
struct
vfsmount
*
,
struct
dentry
*
,
struct
kstat
*
);
extern
int
cifs_getattr
(
struct
vfsmount
*
,
struct
dentry
*
,
struct
kstat
*
);
extern
int
cifs_setattr
(
struct
dentry
*
,
struct
iattr
*
);
extern
int
cifs_setattr
(
struct
dentry
*
,
struct
iattr
*
);
...
@@ -73,19 +74,27 @@ extern const struct inode_operations cifs_dfs_referral_inode_operations;
...
@@ -73,19 +74,27 @@ extern const struct inode_operations cifs_dfs_referral_inode_operations;
/* Functions related to files and directories */
/* Functions related to files and directories */
extern
const
struct
file_operations
cifs_file_ops
;
extern
const
struct
file_operations
cifs_file_ops
;
extern
const
struct
file_operations
cifs_file_direct_ops
;
/* if directio mnt */
extern
const
struct
file_operations
cifs_file_direct_ops
;
/* if directio mnt */
extern
const
struct
file_operations
cifs_file_nobrl_ops
;
extern
const
struct
file_operations
cifs_file_strict_ops
;
/* if strictio mnt */
extern
const
struct
file_operations
cifs_file_direct_nobrl_ops
;
/* no brlocks */
extern
const
struct
file_operations
cifs_file_nobrl_ops
;
/* no brlocks */
extern
const
struct
file_operations
cifs_file_direct_nobrl_ops
;
extern
const
struct
file_operations
cifs_file_strict_nobrl_ops
;
extern
int
cifs_open
(
struct
inode
*
inode
,
struct
file
*
file
);
extern
int
cifs_open
(
struct
inode
*
inode
,
struct
file
*
file
);
extern
int
cifs_close
(
struct
inode
*
inode
,
struct
file
*
file
);
extern
int
cifs_close
(
struct
inode
*
inode
,
struct
file
*
file
);
extern
int
cifs_closedir
(
struct
inode
*
inode
,
struct
file
*
file
);
extern
int
cifs_closedir
(
struct
inode
*
inode
,
struct
file
*
file
);
extern
ssize_t
cifs_user_read
(
struct
file
*
file
,
char
__user
*
read_data
,
extern
ssize_t
cifs_user_read
(
struct
file
*
file
,
char
__user
*
read_data
,
size_t
read_size
,
loff_t
*
poffset
);
size_t
read_size
,
loff_t
*
poffset
);
extern
ssize_t
cifs_strict_readv
(
struct
kiocb
*
iocb
,
const
struct
iovec
*
iov
,
unsigned
long
nr_segs
,
loff_t
pos
);
extern
ssize_t
cifs_user_write
(
struct
file
*
file
,
const
char
__user
*
write_data
,
extern
ssize_t
cifs_user_write
(
struct
file
*
file
,
const
char
__user
*
write_data
,
size_t
write_size
,
loff_t
*
poffset
);
size_t
write_size
,
loff_t
*
poffset
);
extern
ssize_t
cifs_strict_writev
(
struct
kiocb
*
iocb
,
const
struct
iovec
*
iov
,
unsigned
long
nr_segs
,
loff_t
pos
);
extern
int
cifs_lock
(
struct
file
*
,
int
,
struct
file_lock
*
);
extern
int
cifs_lock
(
struct
file
*
,
int
,
struct
file_lock
*
);
extern
int
cifs_fsync
(
struct
file
*
,
struct
dentry
*
,
int
);
extern
int
cifs_fsync
(
struct
file
*
,
struct
dentry
*
,
int
);
extern
int
cifs_strict_fsync
(
struct
file
*
,
struct
dentry
*
,
int
);
extern
int
cifs_flush
(
struct
file
*
,
fl_owner_t
id
);
extern
int
cifs_flush
(
struct
file
*
,
fl_owner_t
id
);
extern
int
cifs_file_mmap
(
struct
file
*
,
struct
vm_area_struct
*
);
extern
int
cifs_file_mmap
(
struct
file
*
,
struct
vm_area_struct
*
);
extern
int
cifs_file_strict_mmap
(
struct
file
*
,
struct
vm_area_struct
*
);
extern
const
struct
file_operations
cifs_dir_ops
;
extern
const
struct
file_operations
cifs_dir_ops
;
extern
int
cifs_dir_open
(
struct
inode
*
inode
,
struct
file
*
file
);
extern
int
cifs_dir_open
(
struct
inode
*
inode
,
struct
file
*
file
);
extern
int
cifs_readdir
(
struct
file
*
file
,
void
*
direntry
,
filldir_t
filldir
);
extern
int
cifs_readdir
(
struct
file
*
file
,
void
*
direntry
,
filldir_t
filldir
);
...
...
sources/2.6.32/cifsglob.h
View file @
edc2bedb
...
@@ -388,6 +388,7 @@ struct cifsInodeInfo {
...
@@ -388,6 +388,7 @@ 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
delete_pending
:
1
;
/* DELETE_ON_CLOSE is set */
bool
delete_pending
:
1
;
/* DELETE_ON_CLOSE is set */
bool
invalid_mapping
:
1
;
/* uptodate cache flag */
u64
server_eof
;
/* current file size on server */
u64
server_eof
;
/* current file size on server */
u64
uniqueid
;
/* server inode number */
u64
uniqueid
;
/* server inode number */
struct
inode
vfs_inode
;
struct
inode
vfs_inode
;
...
...
sources/2.6.32/cifsproto.h
View file @
edc2bedb
...
@@ -70,6 +70,8 @@ extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *);
...
@@ -70,6 +70,8 @@ extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *);
#ifdef CONFIG_CIFS_EXPERIMENTAL
#ifdef CONFIG_CIFS_EXPERIMENTAL
extern
struct
cifsFileInfo
*
find_readable_file
(
struct
cifsInodeInfo
*
);
extern
struct
cifsFileInfo
*
find_readable_file
(
struct
cifsInodeInfo
*
);
#endif
#endif
extern
void
cifs_update_eof
(
struct
cifsInodeInfo
*
cifsi
,
loff_t
offset
,
unsigned
int
bytes_written
);
extern
unsigned
int
smbCalcSize
(
struct
smb_hdr
*
ptr
);
extern
unsigned
int
smbCalcSize
(
struct
smb_hdr
*
ptr
);
extern
unsigned
int
smbCalcSize_LE
(
struct
smb_hdr
*
ptr
);
extern
unsigned
int
smbCalcSize_LE
(
struct
smb_hdr
*
ptr
);
extern
int
decode_negTokenInit
(
unsigned
char
*
security_blob
,
int
length
,
extern
int
decode_negTokenInit
(
unsigned
char
*
security_blob
,
int
length
,
...
@@ -90,10 +92,12 @@ extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601);
...
@@ -90,10 +92,12 @@ extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601);
extern
u64
cifs_UnixTimeToNT
(
struct
timespec
);
extern
u64
cifs_UnixTimeToNT
(
struct
timespec
);
extern
struct
timespec
cnvrtDosUnixTm
(
__le16
le_date
,
__le16
le_time
,
extern
struct
timespec
cnvrtDosUnixTm
(
__le16
le_date
,
__le16
le_time
,
int
offset
);
int
offset
);
extern
void
cifs_set_oplock_level
(
struct
cifsInodeInfo
*
cinode
,
__u32
oplock
);
extern
struct
cifsFileInfo
*
cifs_new_fileinfo
(
struct
inode
*
newinode
,
extern
struct
cifsFileInfo
*
cifs_new_fileinfo
(
struct
inode
*
newinode
,
__u16
fileHandle
,
struct
file
*
file
,
__u16
fileHandle
,
struct
file
*
file
,
struct
vfsmount
*
mnt
,
unsigned
int
oflags
);
struct
vfsmount
*
mnt
,
unsigned
int
oflags
,
__u32
oplock
);
extern
int
cifs_posix_open
(
char
*
full_path
,
struct
inode
**
pinode
,
extern
int
cifs_posix_open
(
char
*
full_path
,
struct
inode
**
pinode
,
struct
vfsmount
*
mnt
,
struct
vfsmount
*
mnt
,
struct
super_block
*
sb
,
struct
super_block
*
sb
,
...
...
sources/2.6.32/connect.c
View file @
edc2bedb
...
@@ -82,6 +82,7 @@ struct smb_vol {
...
@@ -82,6 +82,7 @@ struct smb_vol {
bool
no_xattr
:
1
;
/* set if xattr (EA) support should be disabled*/
bool
no_xattr
:
1
;
/* set if xattr (EA) support should be disabled*/
bool
server_ino
:
1
;
/* use inode numbers from server ie UniqueId */
bool
server_ino
:
1
;
/* use inode numbers from server ie UniqueId */
bool
direct_io
:
1
;
bool
direct_io
:
1
;
bool
strict_io
:
1
;
/* strict cache behavior */
bool
remap
:
1
;
/* set to remap seven reserved chars in filenames */
bool
remap
:
1
;
/* set to remap seven reserved chars in filenames */
bool
posix_paths
:
1
;
/* unset to not ask for posix pathnames. */
bool
posix_paths
:
1
;
/* unset to not ask for posix pathnames. */
bool
no_linux_ext
:
1
;
bool
no_linux_ext
:
1
;
...
@@ -1303,7 +1304,7 @@ cifs_parse_mount_options(char *options, const char *devname,
...
@@ -1303,7 +1304,7 @@ cifs_parse_mount_options(char *options, const char *devname,
}
else
if
(
strnicmp
(
data
,
"wine"
,
4
)
==
0
)
{
}
else
if
(
strnicmp
(
data
,
"wine"
,
4
)
==
0
)
{
vol
->
wine_mode
=
1
;
vol
->
wine_mode
=
1
;
vol
->
mand_lock
=
1
;
vol
->
mand_lock
=
1
;
vol
->
dire
ct_io
=
1
;
vol
->
stri
ct_io
=
1
;
}
else
if
(
strnicmp
(
data
,
"cifsacl"
,
7
)
==
0
)
{
}
else
if
(
strnicmp
(
data
,
"cifsacl"
,
7
)
==
0
)
{
vol
->
cifs_acl
=
1
;
vol
->
cifs_acl
=
1
;
}
else
if
(
strnicmp
(
data
,
"nocifsacl"
,
9
)
==
0
)
{
}
else
if
(
strnicmp
(
data
,
"nocifsacl"
,
9
)
==
0
)
{
...
@@ -1328,6 +1329,8 @@ cifs_parse_mount_options(char *options, const char *devname,
...
@@ -1328,6 +1329,8 @@ cifs_parse_mount_options(char *options, const char *devname,
vol
->
direct_io
=
1
;
vol
->
direct_io
=
1
;
}
else
if
(
strnicmp
(
data
,
"forcedirectio"
,
13
)
==
0
)
{
}
else
if
(
strnicmp
(
data
,
"forcedirectio"
,
13
)
==
0
)
{
vol
->
direct_io
=
1
;
vol
->
direct_io
=
1
;
}
else
if
(
strnicmp
(
data
,
"strictcache"
,
11
)
==
0
)
{
vol
->
strict_io
=
1
;
}
else
if
(
strnicmp
(
data
,
"noac"
,
4
)
==
0
)
{
}
else
if
(
strnicmp
(
data
,
"noac"
,
4
)
==
0
)
{
printk
(
KERN_WARNING
"CIFS: Mount option noac not "
printk
(
KERN_WARNING
"CIFS: Mount option noac not "
"supported. Instead set "
"supported. Instead set "
...
@@ -2191,6 +2194,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
...
@@ -2191,6 +2194,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
cifs_sb
->
mnt_cifs_flags
|=
CIFS_MOUNT_OVERR_GID
;
cifs_sb
->
mnt_cifs_flags
|=
CIFS_MOUNT_OVERR_GID
;
if
(
pvolume_info
->
dynperm
)
if
(
pvolume_info
->
dynperm
)
cifs_sb
->
mnt_cifs_flags
|=
CIFS_MOUNT_DYNPERM
;
cifs_sb
->
mnt_cifs_flags
|=
CIFS_MOUNT_DYNPERM
;
if
(
pvolume_info
->
strict_io
)
cifs_sb
->
mnt_cifs_flags
|=
CIFS_MOUNT_STRICT_IO
;
if
(
pvolume_info
->
direct_io
)
{
if
(
pvolume_info
->
direct_io
)
{
cFYI
(
1
,
(
"mounting share using direct i/o"
));
cFYI
(
1
,
(
"mounting share using direct i/o"
));
cifs_sb
->
mnt_cifs_flags
|=
CIFS_MOUNT_DIRECT_IO
;
cifs_sb
->
mnt_cifs_flags
|=
CIFS_MOUNT_DIRECT_IO
;
...
...
sources/2.6.32/dir.c
View file @
edc2bedb
...
@@ -132,9 +132,9 @@ cifs_bp_rename_retry:
...
@@ -132,9 +132,9 @@ cifs_bp_rename_retry:
struct
cifsFileInfo
*
struct
cifsFileInfo
*
cifs_new_fileinfo
(
struct
inode
*
newinode
,
__u16
fileHandle
,
cifs_new_fileinfo
(
struct
inode
*
newinode
,
__u16
fileHandle
,
struct
file
*
file
,
struct
vfsmount
*
mnt
,
unsigned
int
oflags
)
struct
file
*
file
,
struct
vfsmount
*
mnt
,
unsigned
int
oflags
,
__u32
oplock
)
{
{
int
oplock
=
0
;
struct
cifsFileInfo
*
pCifsFile
;
struct
cifsFileInfo
*
pCifsFile
;
struct
cifsInodeInfo
*
pCifsInode
;
struct
cifsInodeInfo
*
pCifsInode
;
struct
cifs_sb_info
*
cifs_sb
=
CIFS_SB
(
mnt
->
mnt_sb
);
struct
cifs_sb_info
*
cifs_sb
=
CIFS_SB
(
mnt
->
mnt_sb
);
...
@@ -143,9 +143,6 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle,
...
@@ -143,9 +143,6 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle,
if
(
pCifsFile
==
NULL
)
if
(
pCifsFile
==
NULL
)
return
pCifsFile
;
return
pCifsFile
;
if
(
oplockEnabled
)
oplock
=
REQ_OPLOCK
;
pCifsFile
->
netfid
=
fileHandle
;
pCifsFile
->
netfid
=
fileHandle
;
pCifsFile
->
pid
=
current
->
tgid
;
pCifsFile
->
pid
=
current
->
tgid
;
pCifsFile
->
pInode
=
igrab
(
newinode
);
pCifsFile
->
pInode
=
igrab
(
newinode
);
...
@@ -159,9 +156,12 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle,
...
@@ -159,9 +156,12 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle,
atomic_set
(
&
pCifsFile
->
count
,
1
);
atomic_set
(
&
pCifsFile
->
count
,
1
);
slow_work_init
(
&
pCifsFile
->
oplock_break
,
&
cifs_oplock_break_ops
);
slow_work_init
(
&
pCifsFile
->
oplock_break
,
&
cifs_oplock_break_ops
);
pCifsInode
=
CIFS_I
(
newinode
);
if
(
pCifsInode
)
cifs_set_oplock_level
(
pCifsInode
,
oplock
);
write_lock
(
&
GlobalSMBSeslock
);
write_lock
(
&
GlobalSMBSeslock
);
list_add
(
&
pCifsFile
->
tlist
,
&
cifs_sb
->
tcon
->
openFileList
);
list_add
(
&
pCifsFile
->
tlist
,
&
cifs_sb
->
tcon
->
openFileList
);
pCifsInode
=
CIFS_I
(
newinode
);
if
(
pCifsInode
)
{
if
(
pCifsInode
)
{
/* if readable file instance put first in list*/
/* if readable file instance put first in list*/
if
(
oflags
&
FMODE_READ
)
if
(
oflags
&
FMODE_READ
)
...
@@ -169,13 +169,6 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle,
...
@@ -169,13 +169,6 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle,
else
else
list_add_tail
(
&
pCifsFile
->
flist
,
list_add_tail
(
&
pCifsFile
->
flist
,
&
pCifsInode
->
openFileList
);
&
pCifsInode
->
openFileList
);
if
((
oplock
&
0xF
)
==
OPLOCK_EXCLUSIVE
)
{
pCifsInode
->
clientCanCacheAll
=
true
;
pCifsInode
->
clientCanCacheRead
=
true
;
cFYI
(
1
,
(
"Exclusive Oplock inode %p"
,
newinode
));
}
else
if
((
oplock
&
0xF
)
==
OPLOCK_READ
)
pCifsInode
->
clientCanCacheRead
=
true
;
}
}
write_unlock
(
&
GlobalSMBSeslock
);
write_unlock
(
&
GlobalSMBSeslock
);
...
@@ -252,7 +245,8 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
...
@@ -252,7 +245,8 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
}
}
if
(
mnt
)
if
(
mnt
)
cifs_new_fileinfo
(
*
pinode
,
*
pnetfid
,
NULL
,
mnt
,
oflags
);
cifs_new_fileinfo
(
*
pinode
,
*
pnetfid
,
NULL
,
mnt
,
oflags
,
*
poplock
);
posix_open_ret:
posix_open_ret:
kfree
(
presp_data
);
kfree
(
presp_data
);
...
@@ -468,7 +462,7 @@ cifs_create_set_dentry:
...
@@ -468,7 +462,7 @@ cifs_create_set_dentry:
CIFSSMBClose
(
xid
,
tcon
,
fileHandle
);
CIFSSMBClose
(
xid
,
tcon
,
fileHandle
);
}
else
if
(
!
(
posix_create
)
&&
(
newinode
))
{
}
else
if
(
!
(
posix_create
)
&&
(
newinode
))
{
cifs_new_fileinfo
(
newinode
,
fileHandle
,
NULL
,
cifs_new_fileinfo
(
newinode
,
fileHandle
,
NULL
,
nd
->
path
.
mnt
,
oflags
);
nd
->
path
.
mnt
,
oflags
,
oplock
);
}
}
cifs_create_out:
cifs_create_out:
kfree
(
buf
);
kfree
(
buf
);
...
...
sources/2.6.32/file.c
View file @
edc2bedb
...
@@ -151,13 +151,7 @@ cifs_posix_open_inode_helper(struct inode *inode, struct file *file,
...
@@ -151,13 +151,7 @@ cifs_posix_open_inode_helper(struct inode *inode, struct file *file,
} */
} */
psx_client_can_cache:
psx_client_can_cache:
if
((
oplock
&
0xF
)
==
OPLOCK_EXCLUSIVE
)
{
cifs_set_oplock_level
(
pCifsInode
,
oplock
);
pCifsInode
->
clientCanCacheAll
=
true
;
pCifsInode
->
clientCanCacheRead
=
true
;
cFYI
(
1
,
(
"Exclusive Oplock granted on inode %p"
,
file
->
f_path
.
dentry
->
d_inode
));
}
else
if
((
oplock
&
0xF
)
==
OPLOCK_READ
)
pCifsInode
->
clientCanCacheRead
=
true
;
/* will have to change the unlock if we reenable the
/* will have to change the unlock if we reenable the
filemap_fdatawrite (which does not seem necessary */
filemap_fdatawrite (which does not seem necessary */
...
@@ -200,7 +194,7 @@ cifs_fill_filedata(struct file *file)
...
@@ -200,7 +194,7 @@ cifs_fill_filedata(struct file *file)
/* all arguments to this function must be checked for validity in caller */
/* all arguments to this function must be checked for validity in caller */
static
inline
int
cifs_open_inode_helper
(
struct
inode
*
inode
,
struct
file
*
file
,
static
inline
int
cifs_open_inode_helper
(
struct
inode
*
inode
,
struct
file
*
file
,
struct
cifsInodeInfo
*
pCifsInode
,
struct
cifsFileInfo
*
pCifsFile
,
struct
cifsInodeInfo
*
pCifsInode
,
struct
cifsFileInfo
*
pCifsFile
,
struct
cifsTconInfo
*
pTcon
,
int
*
oplock
,
FILE_ALL_INFO
*
buf
,
struct
cifsTconInfo
*
pTcon
,
FILE_ALL_INFO
*
buf
,
char
*
full_path
,
int
xid
)
char
*
full_path
,
int
xid
)
{
{
struct
timespec
temp
;
struct
timespec
temp
;
...
@@ -241,14 +235,6 @@ client_can_cache:
...
@@ -241,14 +235,6 @@ client_can_cache:
rc
=
cifs_get_inode_info
(
&
file
->
f_path
.
dentry
->
d_inode
,
rc
=
cifs_get_inode_info
(
&
file
->
f_path
.
dentry
->
d_inode
,
full_path
,
buf
,
inode
->
i_sb
,
xid
,
NULL
);
full_path
,
buf
,
inode
->
i_sb
,
xid
,
NULL
);
if
((
*
oplock
&
0xF
)
==
OPLOCK_EXCLUSIVE
)
{
pCifsInode
->
clientCanCacheAll
=
true
;
pCifsInode
->
clientCanCacheRead
=
true
;
cFYI
(
1
,
(
"Exclusive Oplock granted on inode %p"
,
file
->
f_path
.
dentry
->
d_inode
));
}
else
if
((
*
oplock
&
0xF
)
==
OPLOCK_READ
)
pCifsInode
->
clientCanCacheRead
=
true
;
return
rc
;
return
rc
;
}
}
...
@@ -398,7 +384,7 @@ int cifs_open(struct inode *inode, struct file *file)
...
@@ -398,7 +384,7 @@ int cifs_open(struct inode *inode, struct file *file)
}
}
pCifsFile
=
cifs_new_fileinfo
(
inode
,
netfid
,
file
,
file
->
f_path
.
mnt
,
pCifsFile
=
cifs_new_fileinfo
(
inode
,
netfid
,
file
,
file
->
f_path
.
mnt
,
file
->
f_flags
);
file
->
f_flags
,
oplock
);
file
->
private_data
=
pCifsFile
;
file
->
private_data
=
pCifsFile
;
if
(
file
->
private_data
==
NULL
)
{
if
(
file
->
private_data
==
NULL
)
{
rc
=
-
ENOMEM
;
rc
=
-
ENOMEM
;
...
@@ -406,7 +392,7 @@ int cifs_open(struct inode *inode, struct file *file)
...
@@ -406,7 +392,7 @@ int cifs_open(struct inode *inode, struct file *file)
}
}
rc
=
cifs_open_inode_helper
(
inode
,
file
,
pCifsInode
,
pCifsFile
,
tcon
,
rc
=
cifs_open_inode_helper
(
inode
,
file
,
pCifsInode
,
pCifsFile
,
tcon
,
&
oplock
,
buf
,
full_path
,
xid
);
buf
,
full_path
,
xid
);
if
(
oplock
&
CIFS_CREATE_ACTION
)
{
if
(
oplock
&
CIFS_CREATE_ACTION
)
{
/* time to set mode which we can not set earlier due to
/* time to set mode which we can not set earlier due to
...
@@ -563,8 +549,7 @@ reopen_success:
...
@@ -563,8 +549,7 @@ reopen_success:
CIFS_I
(
inode
)
->
write_behind_rc
=
rc
;
CIFS_I
(
inode
)
->
write_behind_rc
=
rc
;
/* temporarily disable caching while we
/* temporarily disable caching while we
go to server to get inode info */
go to server to get inode info */
pCifsInode
->
clientCanCacheAll
=
false
;
cifs_set_oplock_level
(
pCifsInode
,
0
);
pCifsInode
->
clientCanCacheRead
=
false
;
if
(
tcon
->
unix_ext
)
if
(
tcon
->
unix_ext
)
rc
=
cifs_get_inode_info_unix
(
&
inode
,
rc
=
cifs_get_inode_info_unix
(
&
inode
,
full_path
,
inode
->
i_sb
,
xid
);
full_path
,
inode
->
i_sb
,
xid
);
...
@@ -578,18 +563,7 @@ reopen_success:
...
@@ -578,18 +563,7 @@ reopen_success:
invalidate the current end of file on the server
invalidate the current end of file on the server
we can not go to the server to get the new inod
we can not go to the server to get the new inod
info */
info */
if
((
oplock
&
0xF
)
==
OPLOCK_EXCLUSIVE
)
{
cifs_set_oplock_level
(
pCifsInode
,
oplock
);
pCifsInode
->
clientCanCacheAll
=
true
;
pCifsInode
->
clientCanCacheRead
=
true
;
cFYI
(
1
,
(
"Exclusive Oplock granted on inode %p"
,
file
->
f_path
.
dentry
->
d_inode
));
}
else
if
((
oplock
&
0xF
)
==
OPLOCK_READ
)
{
pCifsInode
->
clientCanCacheRead
=
true
;
pCifsInode
->
clientCanCacheAll
=
false
;
}
else
{
pCifsInode
->
clientCanCacheRead
=
false
;
pCifsInode
->
clientCanCacheAll
=
false
;
}
cifs_relock_file
(
pCifsFile
);
cifs_relock_file
(
pCifsFile
);
}
}
}
}
...
@@ -665,10 +639,14 @@ int cifs_close(struct inode *inode, struct file *file)
...
@@ -665,10 +639,14 @@ int cifs_close(struct inode *inode, struct file *file)
read_lock
(
&
GlobalSMBSeslock
);
read_lock
(
&
GlobalSMBSeslock
);
if
(
list_empty
(
&
(
CIFS_I
(
inode
)
->
openFileList
)))
{
if
(
list_empty
(
&
(
CIFS_I
(
inode
)
->
openFileList
)))
{
cFYI
(
1
,
(
"closing last open instance for inode %p"
,
inode
));
cFYI
(
1
,
(
"closing last open instance for inode %p"
,
inode
));
/* in strict cache mode we need invalidate mapping on the last
close because it may cause a error when we open this file
again and get at least level II oplock */
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_STRICT_IO
)
CIFS_I
(
inode
)
->
invalid_mapping
=
true
;
/* if the file is not open we do not know if we can cache info
/* if the file is not open we do not know if we can cache info
on this inode, much less write behind and read ahead */
on this inode, much less write behind and read ahead */
CIFS_I
(
inode
)
->
clientCanCacheRead
=
false
;
cifs_set_oplock_level
(
CIFS_I
(
inode
),
0
);
CIFS_I
(
inode
)
->
clientCanCacheAll
=
false
;
}
}
read_unlock
(
&
GlobalSMBSeslock
);
read_unlock
(
&
GlobalSMBSeslock
);
if
((
rc
==
0
)
&&
CIFS_I
(
inode
)
->
write_behind_rc
)
if
((
rc
==
0
)
&&
CIFS_I
(
inode
)
->
write_behind_rc
)
...
@@ -974,7 +952,7 @@ cifs_write_timeout(struct cifsInodeInfo *cifsi, loff_t offset)
...
@@ -974,7 +952,7 @@ cifs_write_timeout(struct cifsInodeInfo *cifsi, loff_t offset)
}
}
/* update the file size (if needed) after a write */
/* update the file size (if needed) after a write */
static
void
void
cifs_update_eof
(
struct
cifsInodeInfo
*
cifsi
,
loff_t
offset
,
cifs_update_eof
(
struct
cifsInodeInfo
*
cifsi
,
loff_t
offset
,
unsigned
int
bytes_written
)
unsigned
int
bytes_written
)
{
{
...
@@ -1545,6 +1523,7 @@ retry:
...
@@ -1545,6 +1523,7 @@ retry:
break
;
break
;
}
}
if
(
n_iov
)
{
if
(
n_iov
)
{
retry_write:
/* Search for a writable handle every time we call
/* Search for a writable handle every time we call
* CIFSSMBWrite2. We can't rely on the last handle
* CIFSSMBWrite2. We can't rely on the last handle
* we used to still be valid
* we used to still be valid
...
@@ -1566,36 +1545,55 @@ retry:
...
@@ -1566,36 +1545,55 @@ retry:
&
bytes_written
,
iov
,
n_iov
,
&
bytes_written
,
iov
,
n_iov
,
long_op
);
long_op
);
cifsFileInfo_put
(
open_file
);
cifsFileInfo_put
(
open_file
);
cifs_update_eof
(
cifsi
,
offset
,
bytes_written
);
}
if
(
rc
||
bytes_written
<
bytes_to_write
)
{
cFYI
(
1
,
(
"Write2 rc=%d, wrote=%u"
,
rc
,
bytes_written
));
cERROR
(
1
,
(
"Write2 ret %d, wrote %d"
,
rc
,
bytes_written
));
/*
/* BB what if continued retry is
* For now, treat a short write as if nothing got
requested via mount flags? */
* written. A zero length write however indicates
if
(
rc
==
-
ENOSPC
)
* ENOSPC or EFBIG. We have no way to know which
set_bit
(
AS_ENOSPC
,
&
mapping
->
flags
);
* though, so call it ENOSPC for now. EFBIG would
else
* get translated to AS_EIO anyway.
set_bit
(
AS_EIO
,
&
mapping
->
flags
);
*
}
else
{
* FIXME: make it take into account the data that did
* get written
*/
if
(
rc
==
0
)
{
if
(
bytes_written
==
0
)
rc
=
-
ENOSPC
;
else
if
(
bytes_written
<
bytes_to_write
)
rc
=
-
EAGAIN
;
}
/* retry on data-integrity flush */
if
(
wbc
->
sync_mode
==
WB_SYNC_ALL
&&
rc
==
-
EAGAIN
)
goto
retry_write
;
/* fix the stats and EOF */
if
(
bytes_written
>
0
)
{
cifs_stats_bytes_written
(
cifs_sb
->
tcon
,
cifs_stats_bytes_written
(
cifs_sb
->
tcon
,
bytes_written
);
bytes_written
);
}
cifs_update_eof
(
cifsi
,
offset
,
bytes_written
);
}
}
for
(
i
=
0
;
i
<
n_iov
;
i
++
)
{
for
(
i
=
0
;
i
<
n_iov
;
i
++
)
{
page
=
pvec
.
pages
[
first
+
i
];
page
=
pvec
.
pages
[
first
+
i
];
/* Should we also set page error on
/* on retryable write error, redirty page */
success rc but too little data written? */
if
(
rc
==
-
EAGAIN
)
/* BB investigate retry logic on temporary
redirty_page_for_writepage
(
wbc
,
page
);
server crash cases and how recovery works
else
if
(
rc
!=
0
)
when page marked as error */
if
(
rc
)
SetPageError
(
page
);
SetPageError
(
page
);
kunmap
(
page
);
kunmap
(
page
);
unlock_page
(
page
);
unlock_page
(
page
);
end_page_writeback
(
page
);
end_page_writeback
(
page
);
page_cache_release
(
page
);
page_cache_release
(
page
);
}
}
if
(
rc
!=
-
EAGAIN
)
mapping_set_error
(
mapping
,
rc
);
else
rc
=
0
;
if
((
wbc
->
nr_to_write
-=
n_iov
)
<=
0
)
if
((
wbc
->
nr_to_write
-=
n_iov
)
<=
0
)
done
=
1
;
done
=
1
;
index
=
next
;
index
=
next
;
...
@@ -1706,7 +1704,7 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
...
@@ -1706,7 +1704,7 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
return
rc
;
return
rc
;
}
}
int
cifs_fsync
(
struct
file
*
file
,
struct
dentry
*
dentry
,
int
datasync
)
int
cifs_
strict_
fsync
(
struct
file
*
file
,
struct
dentry
*
dentry
,
int
datasync
)
{
{
int
xid
;
int
xid
;
int
rc
=
0
;
int
rc
=
0
;
...
@@ -1714,21 +1712,40 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
...
@@ -1714,21 +1712,40 @@ int cifs_fsync(struct file *file, struct dentry *dentry, int datasync)
struct
cifsFileInfo
*
smbfile
=
struct
cifsFileInfo
*
smbfile
=
(
struct
cifsFileInfo
*
)
file
->
private_data
;
(
struct
cifsFileInfo
*
)
file
->
private_data
;
struct
inode
*
inode
=
file
->
f_path
.
dentry
->
d_inode
;
struct
inode
*
inode
=
file
->
f_path
.
dentry
->
d_inode
;
struct
cifs_sb_info
*
cifs_sb
=
CIFS_SB
(
inode
->
i_sb
);
xid
=
GetXid
();
xid
=
GetXid
();
cFYI
(
1
,
(
"Sync file - name: %s datasync: 0x%x"
,
cFYI
(
1
,
(
"Sync file - name: %s datasync: 0x%x"
,
dentry
->
d_name
.
name
,
datasync
));
dentry
->
d_name
.
name
,
datasync
));
rc
=
filemap_write_and_wait
(
inode
->
i_mapping
);
if
(
!
CIFS_I
(
inode
)
->
clientCanCacheRead
)
if
(
rc
==
0
)
{
cifs_invalidate_mapping
(
inode
);
rc
=
CIFS_I
(
inode
)
->
write_behind_rc
;
CIFS_I
(
inode
)
->
write_behind_rc
=
0
;
tcon
=
cifs_sb
->
tcon
;
tcon
=
CIFS_SB
(
inode
->
i_sb
)
->
tcon
;
if
(
!
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NOSSYNC
))
if
(
!
rc
&&
tcon
&&
smbfile
&&
rc
=
CIFSSMBFlush
(
xid
,
tcon
,
smbfile
->
netfid
);
!
(
CIFS_SB
(
inode
->
i_sb
)
->
mnt_cifs_flags
&
CIFS_MOUNT_NOSSYNC
))
FreeXid
(
xid
);
return
rc
;
}
int
cifs_fsync
(
struct
file
*
file
,
struct
dentry
*
dentry
,
int
datasync
)
{
int
xid
;
int
rc
=
0
;
struct
cifsTconInfo
*
tcon
;
struct
cifsFileInfo
*
smbfile
=
file
->
private_data
;
struct
cifs_sb_info
*
cifs_sb
=
CIFS_SB
(
dentry
->
d_sb
);
xid
=
GetXid
();
cFYI
(
1
,
(
"Sync file - name: %s datasync: 0x%x"
,
dentry
->
d_name
.
name
,
datasync
));
tcon
=
cifs_sb
->
tcon
;
if
(
!
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NOSSYNC
))
rc
=
CIFSSMBFlush
(
xid
,
tcon
,
smbfile
->
netfid
);
rc
=
CIFSSMBFlush
(
xid
,
tcon
,
smbfile
->
netfid
);
}
FreeXid
(
xid
);
FreeXid
(
xid
);
return
rc
;
return
rc
;
...
@@ -1792,21 +1809,247 @@ int cifs_flush(struct file *file, fl_owner_t id)
...
@@ -1792,21 +1809,247 @@ int cifs_flush(struct file *file, fl_owner_t id)
return
rc
;
return
rc
;
}
}
s
size_t
cifs_user_read
(
struct
file
*
file
,
char
__user
*
read_data
,
s
tatic
int
size_t
read_size
,
loff_t
*
poffset
)
cifs_write_allocate_pages
(
struct
page
**
pages
,
unsigned
long
num_pages
)
{
{
int
rc
=
-
EACCES
;
int
rc
=
0
;
unsigned
long
i
;
for
(
i
=
0
;
i
<
num_pages
;
i
++
)
{
pages
[
i
]
=
alloc_page
(
__GFP_HIGHMEM
);
if
(
!
pages
[
i
])
{
/*
* save number of pages we have already allocated and
* return with ENOMEM error
*/
num_pages
=
i
;
rc
=
-
ENOMEM
;
goto
error
;
}
}
return
rc
;
error:
for
(
i
=
0
;
i
<
num_pages
;
i
++
)
put_page
(
pages
[
i
]);
return
rc
;
}
static
inline
size_t
get_numpages
(
const
size_t
wsize
,
const
size_t
len
,
size_t
*
cur_len
)
{
size_t
num_pages
;
size_t
clen
;
clen
=
min_t
(
const
size_t
,
len
,
wsize
);
num_pages
=
clen
/
PAGE_CACHE_SIZE
;
if
(
clen
%
PAGE_CACHE_SIZE
)
num_pages
++
;
if
(
cur_len
)
*
cur_len
=
clen
;
return
num_pages
;
}
static
ssize_t
cifs_iovec_write
(
struct
file
*
file
,
const
struct
iovec
*
iov
,
unsigned
long
nr_segs
,
loff_t
*
poffset
)
{
unsigned
int
written
;
unsigned
long
num_pages
,
npages
,
i
;
size_t
copied
,
len
,
cur_len
;
ssize_t
total_written
=
0
;
struct
kvec
*
to_send
;
struct
page
**
pages
;
struct
iov_iter
it
;
struct
inode
*
inode
;
struct
cifsFileInfo
*
open_file
;
struct
cifsTconInfo
*
pTcon
;
struct
cifs_sb_info
*
cifs_sb
;
int
xid
,
rc
;
__u32
netpid
;
len
=
iov_length
(
iov
,
nr_segs
);
if
(
!
len
)
return
0
;
rc
=
generic_write_checks
(
file
,
poffset
,
&
len
,
0
);
if
(
rc
)
return
rc
;
cifs_sb
=
CIFS_SB
(
file
->
f_path
.
dentry
->
d_sb
);
num_pages
=
get_numpages
(
cifs_sb
->
wsize
,
len
,
&
cur_len
);
pages
=
kmalloc
(
sizeof
(
struct
pages
*
)
*
num_pages
,
GFP_KERNEL
);
if
(
!
pages
)
return
-
ENOMEM
;
to_send
=
kmalloc
(
sizeof
(
struct
kvec
)
*
(
num_pages
+
1
),
GFP_KERNEL
);
if
(
!
to_send
)
{
kfree
(
pages
);
return
-
ENOMEM
;
}
rc
=
cifs_write_allocate_pages
(
pages
,
num_pages
);
if
(
rc
)
{
kfree
(
pages
);
kfree
(
to_send
);
return
rc
;
}
xid
=
GetXid
();
if
(
file
->
private_data
==
NULL
)
{
rc
=
-
EBADF
;
for
(
i
=
0
;
i
<
num_pages
;
i
++
)
put_page
(
pages
[
i
]);
kfree
(
pages
);
kfree
(
to_send
);
FreeXid
(
xid
);
return
rc
;
}
open_file
=
file
->
private_data
;
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_WINE_MODE
)
netpid
=
open_file
->
pid
;
else
netpid
=
current
->
tgid
;
pTcon
=
cifs_sb
->
tcon
;
inode
=
file
->
f_path
.
dentry
->
d_inode
;
iov_iter_init
(
&
it
,
iov
,
nr_segs
,
len
,
0
);
npages
=
num_pages
;
do
{
size_t
save_len
=
cur_len
;
for
(
i
=
0
;
i
<
npages
;
i
++
)
{
copied
=
min_t
(
const
size_t
,
cur_len
,
PAGE_CACHE_SIZE
);
copied
=
iov_iter_copy_from_user
(
pages
[
i
],
&
it
,
0
,
copied
);
cur_len
-=
copied
;
iov_iter_advance
(
&
it
,
copied
);
to_send
[
i
+
1
].
iov_base
=
kmap
(
pages
[
i
]);
to_send
[
i
+
1
].
iov_len
=
copied
;
}
cur_len
=
save_len
-
cur_len
;
do
{
if
(
open_file
->
invalidHandle
)
{
rc
=
cifs_reopen_file
(
file
,
false
);
if
(
rc
!=
0
)
break
;
}
rc
=
CIFSSMBWrite2
(
xid
,
pTcon
,
open_file
->
netfid
,
netpid
,
cur_len
,
*
poffset
,
&
written
,
to_send
,
npages
,
0
);
}
while
(
rc
==
-
EAGAIN
);
for
(
i
=
0
;
i
<
npages
;
i
++
)
kunmap
(
pages
[
i
]);
if
(
written
)
{
len
-=
written
;
total_written
+=
written
;
cifs_update_eof
(
CIFS_I
(
inode
),
*
poffset
,
written
);
*
poffset
+=
written
;
}
else
if
(
rc
<
0
)
{
if
(
!
total_written
)
total_written
=
rc
;
break
;
}
/* get length and number of kvecs of the next write */
npages
=
get_numpages
(
cifs_sb
->
wsize
,
len
,
&
cur_len
);
}
while
(
len
>
0
);
if
(
total_written
>
0
)
{
spin_lock
(
&
inode
->
i_lock
);
if
(
*
poffset
>
inode
->
i_size
)
i_size_write
(
inode
,
*
poffset
);
spin_unlock
(
&
inode
->
i_lock
);
}
cifs_stats_bytes_written
(
pTcon
,
total_written
);
mark_inode_dirty_sync
(
inode
);
for
(
i
=
0
;
i
<
num_pages
;
i
++
)
put_page
(
pages
[
i
]);
kfree
(
to_send
);
kfree
(
pages
);
FreeXid
(
xid
);
return
total_written
;
}
static
ssize_t
cifs_user_writev
(
struct
kiocb
*
iocb
,
const
struct
iovec
*
iov
,
unsigned
long
nr_segs
,
loff_t
pos
)
{
ssize_t
written
;
struct
inode
*
inode
;
inode
=
iocb
->
ki_filp
->
f_path
.
dentry
->
d_inode
;
/*
* BB - optimize the way when signing is disabled. We can drop this
* extra memory-to-memory copying and use iovec buffers for constructing
* write request.
*/
written
=
cifs_iovec_write
(
iocb
->
ki_filp
,
iov
,
nr_segs
,
&
pos
);
if
(
written
>
0
)
{
CIFS_I
(
inode
)
->
invalid_mapping
=
true
;
iocb
->
ki_pos
=
pos
;
}
return
written
;
}
ssize_t
cifs_strict_writev
(
struct
kiocb
*
iocb
,
const
struct
iovec
*
iov
,
unsigned
long
nr_segs
,
loff_t
pos
)
{
struct
inode
*
inode
;
inode
=
iocb
->
ki_filp
->
f_path
.
dentry
->
d_inode
;
if
(
CIFS_I
(
inode
)
->
clientCanCacheAll
)
return
generic_file_aio_write
(
iocb
,
iov
,
nr_segs
,
pos
);
/*
* In strict cache mode we need to write the data to the server exactly
* from the pos to pos+len-1 rather than flush all affected pages
* because it may cause a error with mandatory locks on these pages but
* not on the region from pos to ppos+len-1.
*/
return
cifs_user_writev
(
iocb
,
iov
,
nr_segs
,
pos
);
}
static
ssize_t
cifs_iovec_read
(
struct
file
*
file
,
const
struct
iovec
*
iov
,
unsigned
long
nr_segs
,
loff_t
*
poffset
)
{
int
rc
;
int
xid
;
ssize_t
total_read
;
unsigned
int
bytes_read
=
0
;
unsigned
int
bytes_read
=
0
;
unsigned
int
total_read
=
0
;
size_t
len
,
cur_len
;
unsigned
int
current_read_size
;
int
iov_offset
=
0
;
struct
cifs_sb_info
*
cifs_sb
;
struct
cifs_sb_info
*
cifs_sb
;
struct
cifsTconInfo
*
pTcon
;
struct
cifsTconInfo
*
pTcon
;
int
xid
;
struct
cifsFileInfo
*
open_file
;
struct
cifsFileInfo
*
open_file
;
char
*
smb_read_data
;
char
__user
*
current_offset
;
struct
smb_com_read_rsp
*
pSMBr
;
struct
smb_com_read_rsp
*
pSMBr
;
__u32
netpid
;
__u32
netpid
;
char
*
read_data
;
if
(
!
nr_segs
)
return
0
;
len
=
iov_length
(
iov
,
nr_segs
);
if
(
!
len
)
return
0
;
xid
=
GetXid
();
xid
=
GetXid
();
cifs_sb
=
CIFS_SB
(
file
->
f_path
.
dentry
->
d_sb
);
cifs_sb
=
CIFS_SB
(
file
->
f_path
.
dentry
->
d_sb
);
...
@@ -1827,13 +2070,11 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
...
@@ -1827,13 +2070,11 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
if
((
file
->
f_flags
&
O_ACCMODE
)
==
O_WRONLY
)
if
((
file
->
f_flags
&
O_ACCMODE
)
==
O_WRONLY
)
cFYI
(
1
,
(
"attempting read on write only file instance"
));
cFYI
(
1
,
(
"attempting read on write only file instance"
));
for
(
total_read
=
0
,
current_offset
=
read_data
;
for
(
total_read
=
0
;
total_read
<
len
;
total_read
+=
bytes_read
)
{
read_size
>
total_read
;
cur_len
=
min_t
(
const
size_t
,
len
-
total_read
,
cifs_sb
->
rsize
);
total_read
+=
bytes_read
,
current_offset
+=
bytes_read
)
{
current_read_size
=
min_t
(
const
int
,
read_size
-
total_read
,
cifs_sb
->
rsize
);
rc
=
-
EAGAIN
;
rc
=
-
EAGAIN
;
smb_read_data
=
NULL
;
read_data
=
NULL
;
while
(
rc
==
-
EAGAIN
)
{
while
(
rc
==
-
EAGAIN
)
{
int
buf_type
=
CIFS_NO_BUFFER
;
int
buf_type
=
CIFS_NO_BUFFER
;
if
((
open_file
->
invalidHandle
)
&&
if
((
open_file
->
invalidHandle
)
&&
...
@@ -1842,27 +2083,25 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
...
@@ -1842,27 +2083,25 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
if
(
rc
!=
0
)
if
(
rc
!=
0
)
break
;
break
;
}
}
rc
=
CIFSSMBRead
(
xid
,
pTcon
,
rc
=
CIFSSMBRead
(
xid
,
pTcon
,
open_file
->
netfid
,
open_file
->
netfid
,
netpid
,
netpid
,
cur_len
,
*
poffset
,
&
bytes_read
,
current_read_size
,
*
poffset
,
&
read_data
,
&
buf_type
);
&
bytes_read
,
&
smb_read_data
,
pSMBr
=
(
struct
smb_com_read_rsp
*
)
read_data
;
&
buf_type
);
if
(
read_data
)
{
pSMBr
=
(
struct
smb_com_read_rsp
*
)
smb_read_data
;
char
*
data_offset
=
read_data
+
4
+
if
(
smb_read_data
)
{
le16_to_cpu
(
pSMBr
->
DataOffset
);
if
(
copy_to_user
(
current_offset
,
if
(
memcpy_toiovecend
(
iov
,
data_offset
,
smb_read_data
+
iov_offset
,
bytes_read
))
4
/* RFC1001 length field */
+
le16_to_cpu
(
pSMBr
->
DataOffset
),
bytes_read
))
rc
=
-
EFAULT
;
rc
=
-
EFAULT
;
if
(
buf_type
==
CIFS_SMALL_BUFFER
)
if
(
buf_type
==
CIFS_SMALL_BUFFER
)
cifs_small_buf_release
(
smb_
read_data
);
cifs_small_buf_release
(
read_data
);
else
if
(
buf_type
==
CIFS_LARGE_BUFFER
)
else
if
(
buf_type
==
CIFS_LARGE_BUFFER
)
cifs_buf_release
(
smb_read_data
);
cifs_buf_release
(
read_data
);
smb_read_data
=
NULL
;
read_data
=
NULL
;
iov_offset
+=
bytes_read
;
}
}
}
}
if
(
rc
||
(
bytes_read
==
0
))
{
if
(
rc
||
(
bytes_read
==
0
))
{
if
(
total_read
)
{
if
(
total_read
)
{
break
;
break
;
...
@@ -1875,10 +2114,54 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
...
@@ -1875,10 +2114,54 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
*
poffset
+=
bytes_read
;
*
poffset
+=
bytes_read
;
}
}
}
}
FreeXid
(
xid
);
FreeXid
(
xid
);
return
total_read
;
return
total_read
;
}
}
ssize_t
cifs_user_read
(
struct
file
*
file
,
char
__user
*
read_data
,
size_t
read_size
,
loff_t
*
poffset
)
{
struct
iovec
iov
;
iov
.
iov_base
=
read_data
;
iov
.
iov_len
=
read_size
;
return
cifs_iovec_read
(
file
,
&
iov
,
1
,
poffset
);
}
static
ssize_t
cifs_user_readv
(
struct
kiocb
*
iocb
,
const
struct
iovec
*
iov
,
unsigned
long
nr_segs
,
loff_t
pos
)
{
ssize_t
read
;
read
=
cifs_iovec_read
(
iocb
->
ki_filp
,
iov
,
nr_segs
,
&
pos
);
if
(
read
>
0
)
iocb
->
ki_pos
=
pos
;
return
read
;
}
ssize_t
cifs_strict_readv
(
struct
kiocb
*
iocb
,
const
struct
iovec
*
iov
,
unsigned
long
nr_segs
,
loff_t
pos
)
{
struct
inode
*
inode
;
inode
=
iocb
->
ki_filp
->
f_path
.
dentry
->
d_inode
;
if
(
CIFS_I
(
inode
)
->
clientCanCacheRead
)
return
generic_file_aio_read
(
iocb
,
iov
,
nr_segs
,
pos
);
/*
* In strict cache mode we need to read from the server all the time
* if we don't have level II oplock because the server can delay mtime
* change - so we can't make a decision about inode invalidating.
* And we can also fail with pagereading if there are mandatory locks
* on pages affected by this read but not on the region from pos to
* pos+len-1.
*/
return
cifs_user_readv
(
iocb
,
iov
,
nr_segs
,
pos
);
}
static
ssize_t
cifs_read
(
struct
file
*
file
,
char
*
read_data
,
size_t
read_size
,
static
ssize_t
cifs_read
(
struct
file
*
file
,
char
*
read_data
,
size_t
read_size
,
loff_t
*
poffset
)
loff_t
*
poffset
)
...
@@ -1956,6 +2239,21 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
...
@@ -1956,6 +2239,21 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
return
total_read
;
return
total_read
;
}
}
int
cifs_file_strict_mmap
(
struct
file
*
file
,
struct
vm_area_struct
*
vma
)
{
int
rc
,
xid
;
struct
inode
*
inode
=
file
->
f_path
.
dentry
->
d_inode
;
xid
=
GetXid
();
if
(
!
CIFS_I
(
inode
)
->
clientCanCacheRead
)
cifs_invalidate_mapping
(
inode
);
rc
=
generic_file_mmap
(
file
,
vma
);
FreeXid
(
xid
);
return
rc
;
}
int
cifs_file_mmap
(
struct
file
*
file
,
struct
vm_area_struct
*
vma
)
int
cifs_file_mmap
(
struct
file
*
file
,
struct
vm_area_struct
*
vma
)
{
{
struct
dentry
*
dentry
=
file
->
f_path
.
dentry
;
struct
dentry
*
dentry
=
file
->
f_path
.
dentry
;
...
...
sources/2.6.32/inode.c
View file @
edc2bedb
...
@@ -42,13 +42,17 @@ static void cifs_set_ops(struct inode *inode, const bool is_dfs_referral)
...
@@ -42,13 +42,17 @@ static void cifs_set_ops(struct inode *inode, const bool is_dfs_referral)
inode
->
i_fop
=
&
cifs_file_direct_nobrl_ops
;
inode
->
i_fop
=
&
cifs_file_direct_nobrl_ops
;
else
else
inode
->
i_fop
=
&
cifs_file_direct_ops
;
inode
->
i_fop
=
&
cifs_file_direct_ops
;
}
else
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_STRICT_IO
)
{
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NO_BRL
)
inode
->
i_fop
=
&
cifs_file_strict_nobrl_ops
;
else
inode
->
i_fop
=
&
cifs_file_strict_ops
;
}
else
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NO_BRL
)
}
else
if
(
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_NO_BRL
)
inode
->
i_fop
=
&
cifs_file_nobrl_ops
;
inode
->
i_fop
=
&
cifs_file_nobrl_ops
;
else
{
/* not direct, send byte range locks */
else
{
/* not direct, send byte range locks */
inode
->
i_fop
=
&
cifs_file_ops
;
inode
->
i_fop
=
&
cifs_file_ops
;
}
}
/* check if server can support readpages */
/* check if server can support readpages */
if
(
cifs_sb
->
tcon
->
ses
->
server
->
maxBuf
<
if
(
cifs_sb
->
tcon
->
ses
->
server
->
maxBuf
<
PAGE_CACHE_SIZE
+
MAX_CIFS_HDR_SIZE
)
PAGE_CACHE_SIZE
+
MAX_CIFS_HDR_SIZE
)
...
@@ -1409,16 +1413,64 @@ cifs_rename_exit:
...
@@ -1409,16 +1413,64 @@ cifs_rename_exit:
return
rc
;
return
rc
;
}
}
static
bool
cifs_check_inval
(
struct
inode
*
inode
)
{
struct
cifsInodeInfo
*
cifs_i
=
CIFS_I
(
inode
);
if
(
cifs_i
->
clientCanCacheRead
)
return
false
;
if
(
!
lookupCacheEnabled
)
return
true
;
if
(
cifs_i
->
time
==
0
)
return
true
;
/* FIXME: the actimeo should be tunable */
if
(
time_after_eq
(
jiffies
,
cifs_i
->
time
+
HZ
))
return
true
;
/* hardlinked files get "special" treatment */
if
(
S_ISREG
(
inode
->
i_mode
)
&&
inode
->
i_nlink
!=
1
)
return
true
;
return
false
;
}
/*
* Zap the cache. Called when invalid_mapping flag is set.
*/
void
cifs_invalidate_mapping
(
struct
inode
*
inode
)
{
int
rc
;
struct
cifsInodeInfo
*
cifs_i
=
CIFS_I
(
inode
);
cifs_i
->
invalid_mapping
=
false
;
/* write back any cached data */
if
(
inode
->
i_mapping
&&
inode
->
i_mapping
->
nrpages
!=
0
)
{
rc
=
filemap_write_and_wait
(
inode
->
i_mapping
);
if
(
rc
)
cifs_i
->
write_behind_rc
=
rc
;
rc
=
invalidate_inode_pages2
(
inode
->
i_mapping
);
if
(
rc
)
{
cERROR
(
1
,
(
"%s: could not invalidate inode %p"
,
__func__
,
inode
));
cifs_i
->
invalid_mapping
=
true
;
}
}
}
int
cifs_revalidate
(
struct
dentry
*
direntry
)
int
cifs_revalidate
(
struct
dentry
*
direntry
)
{
{
int
xid
;
int
xid
;
int
rc
=
0
,
wbrc
=
0
;
int
rc
=
0
;
char
*
full_path
;
char
*
full_path
;
struct
cifs_sb_info
*
cifs_sb
;
struct
cifs_sb_info
*
cifs_sb
;
struct
cifsInodeInfo
*
cifsInode
;
struct
cifsInodeInfo
*
cifsInode
;
loff_t
local_size
;
loff_t
local_size
;
struct
timespec
local_mtime
;
struct
timespec
local_mtime
;
bool
invalidate_inode
=
false
;
if
(
direntry
->
d_inode
==
NULL
)
if
(
direntry
->
d_inode
==
NULL
)
return
-
ENOENT
;
return
-
ENOENT
;
...
@@ -1428,10 +1480,6 @@ int cifs_revalidate(struct dentry *direntry)
...
@@ -1428,10 +1480,6 @@ int cifs_revalidate(struct dentry *direntry)
if
(
cifsInode
==
NULL
)
if
(
cifsInode
==
NULL
)
return
-
ENOENT
;
return
-
ENOENT
;
/* no sense revalidating inode info on file that no one can write */
if
(
CIFS_I
(
direntry
->
d_inode
)
->
clientCanCacheRead
)
return
rc
;
xid
=
GetXid
();
xid
=
GetXid
();
cifs_sb
=
CIFS_SB
(
direntry
->
d_sb
);
cifs_sb
=
CIFS_SB
(
direntry
->
d_sb
);
...
@@ -1449,19 +1497,8 @@ int cifs_revalidate(struct dentry *direntry)
...
@@ -1449,19 +1497,8 @@ 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
)
{
if
(
!
cifs_check_inval
(
direntry
->
d_inode
))
/* was set to zero previously to force revalidate */
goto
check_inval
;
}
else
if
(
time_before
(
jiffies
,
cifsInode
->
time
+
HZ
)
&&
lookupCacheEnabled
)
{
if
((
S_ISREG
(
direntry
->
d_inode
->
i_mode
)
==
0
)
||
(
direntry
->
d_inode
->
i_nlink
==
1
))
{
kfree
(
full_path
);
FreeXid
(
xid
);
return
rc
;
}
else
{
cFYI
(
1
,
(
"Have to revalidate file due to hardlinks"
));
}
}
/* save mtime and size */
/* save mtime and size */
local_mtime
=
direntry
->
d_inode
->
i_mtime
;
local_mtime
=
direntry
->
d_inode
->
i_mtime
;
...
@@ -1495,48 +1532,16 @@ int cifs_revalidate(struct dentry *direntry)
...
@@ -1495,48 +1532,16 @@ int cifs_revalidate(struct dentry *direntry)
(
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 */
cifsInode
->
invalid_mapping
=
true
;
if
(
cifsInode
->
clientCanCacheRead
)
{
/* no need to invalidate inode pages since we were the
only ones who could have modified the file and the
server copy is staler than ours */
}
else
{
invalidate_inode
=
true
;
}
}
}
/* can not grab this sem since kernel filesys locking documentation
/* can not grab this sem since kernel filesys locking documentation
indicates i_mutex may be taken by the kernel on lookup and rename
indicates i_mutex may be taken by the kernel on lookup and rename
which could deadlock if we grab the i_mutex here as well */
which could deadlock if we grab the i_mutex here as well */
check_inval:
/* mutex_lock(&direntry->d_inode->i_mutex);*/
/* mutex_lock(&direntry->d_inode->i_mutex);*/
/* need to write out dirty pages here */
if
(
cifsInode
->
invalid_mapping
)
if
(
direntry
->
d_inode
->
i_mapping
)
{
cifs_invalidate_mapping
(
direntry
->
d_inode
);
/* do we need to lock inode until after invalidate completes
below? */
wbrc
=
filemap_fdatawrite
(
direntry
->
d_inode
->
i_mapping
);
if
(
wbrc
)
CIFS_I
(
direntry
->
d_inode
)
->
write_behind_rc
=
wbrc
;
}
if
(
invalidate_inode
)
{
/* shrink_dcache not necessary now that cifs dentry ops
are exported for negative dentries */
/* if (S_ISDIR(direntry->d_inode->i_mode))
shrink_dcache_parent(direntry); */
if
(
S_ISREG
(
direntry
->
d_inode
->
i_mode
))
{
if
(
direntry
->
d_inode
->
i_mapping
)
{
wbrc
=
filemap_fdatawait
(
direntry
->
d_inode
->
i_mapping
);
if
(
wbrc
)
CIFS_I
(
direntry
->
d_inode
)
->
write_behind_rc
=
wbrc
;
}
/* may eventually have to do this for open files too */
if
(
list_empty
(
&
(
cifsInode
->
openFileList
)))
{
/* changed on server - flush read ahead pages */
cFYI
(
1
,
(
"Invalidating read ahead data on "
"closed file"
));
invalidate_remote_inode
(
direntry
->
d_inode
);
}
}
}
/* mutex_unlock(&direntry->d_inode->i_mutex); */
/* mutex_unlock(&direntry->d_inode->i_mutex); */
kfree
(
full_path
);
kfree
(
full_path
);
...
...
sources/2.6.32/misc.c
View file @
edc2bedb
...
@@ -569,6 +569,10 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
...
@@ -569,6 +569,10 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
if
(
pSMB
->
Fid
!=
netfile
->
netfid
)
if
(
pSMB
->
Fid
!=
netfile
->
netfid
)
continue
;
continue
;
cFYI
(
1
,
(
"file id match, oplock break"
));
pCifsInode
=
CIFS_I
(
netfile
->
pInode
);
cifs_set_oplock_level
(
pCifsInode
,
pSMB
->
OplockLevel
?
OPLOCK_READ
:
0
);
/*
/*
* don't do anything if file is about to be
* don't do anything if file is about to be
* closed anyway.
* closed anyway.
...
@@ -579,11 +583,6 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
...
@@ -579,11 +583,6 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv)
return
true
;
return
true
;
}
}
cFYI
(
1
,
(
"file id match, oplock break"
));
pCifsInode
=
CIFS_I
(
netfile
->
pInode
);
pCifsInode
->
clientCanCacheAll
=
false
;
if
(
pSMB
->
OplockLevel
==
0
)
pCifsInode
->
clientCanCacheRead
=
false
;
rc
=
slow_work_enqueue
(
&
netfile
->
oplock_break
);
rc
=
slow_work_enqueue
(
&
netfile
->
oplock_break
);
if
(
rc
)
{
if
(
rc
)
{
cERROR
(
1
,
(
"failed to enqueue oplock "
cERROR
(
1
,
(
"failed to enqueue oplock "
...
@@ -729,3 +728,23 @@ cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb)
...
@@ -729,3 +728,23 @@ cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb)
cifs_sb
->
tcon
->
treeName
));
cifs_sb
->
tcon
->
treeName
));
}
}
}
}
void
cifs_set_oplock_level
(
struct
cifsInodeInfo
*
cinode
,
__u32
oplock
)
{
oplock
&=
0xF
;
if
(
oplock
==
OPLOCK_EXCLUSIVE
)
{
cinode
->
clientCanCacheAll
=
true
;
cinode
->
clientCanCacheRead
=
true
;
cFYI
(
1
,
(
"Exclusive Oplock granted on inode %p"
,
&
cinode
->
vfs_inode
));
}
else
if
(
oplock
==
OPLOCK_READ
)
{
cinode
->
clientCanCacheAll
=
false
;
cinode
->
clientCanCacheRead
=
true
;
cFYI
(
1
,
(
"Level II Oplock granted on inode %p"
,
&
cinode
->
vfs_inode
));
}
else
{
cinode
->
clientCanCacheAll
=
false
;
cinode
->
clientCanCacheRead
=
false
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment