Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
276a74a4
Commit
276a74a4
authored
Mar 03, 2009
by
Steve French
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[CIFS] Use posix open on file open when server supports it
Signed-off-by:
Steve French
<
sfrench@us.ibm.com
>
parent
fcc7c09d
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
111 additions
and
13 deletions
+111
-13
fs/cifs/file.c
fs/cifs/file.c
+111
-13
No files found.
fs/cifs/file.c
View file @
276a74a4
...
...
@@ -124,6 +124,80 @@ static inline int cifs_get_disposition(unsigned int flags)
return
FILE_OPEN
;
}
/* all arguments to this function must be checked for validity in caller */
static
inline
int
cifs_posix_open_inode_helper
(
struct
inode
*
inode
,
struct
file
*
file
,
struct
cifsInodeInfo
*
pCifsInode
,
struct
cifsFileInfo
*
pCifsFile
,
int
oplock
,
u16
netfid
)
{
struct
cifs_sb_info
*
cifs_sb
=
CIFS_SB
(
inode
->
i_sb
);
/* struct timespec temp; */
/* BB REMOVEME BB */
file
->
private_data
=
kmalloc
(
sizeof
(
struct
cifsFileInfo
),
GFP_KERNEL
);
if
(
file
->
private_data
==
NULL
)
return
-
ENOMEM
;
pCifsFile
=
cifs_init_private
(
file
->
private_data
,
inode
,
file
,
netfid
);
write_lock
(
&
GlobalSMBSeslock
);
list_add
(
&
pCifsFile
->
tlist
,
&
cifs_sb
->
tcon
->
openFileList
);
pCifsInode
=
CIFS_I
(
file
->
f_path
.
dentry
->
d_inode
);
if
(
pCifsInode
==
NULL
)
{
write_unlock
(
&
GlobalSMBSeslock
);
return
-
EINVAL
;
}
/* want handles we can use to read with first
in the list so we do not have to walk the
list to search for one in write_begin */
if
((
file
->
f_flags
&
O_ACCMODE
)
==
O_WRONLY
)
{
list_add_tail
(
&
pCifsFile
->
flist
,
&
pCifsInode
->
openFileList
);
}
else
{
list_add
(
&
pCifsFile
->
flist
,
&
pCifsInode
->
openFileList
);
}
if
(
pCifsInode
->
clientCanCacheRead
)
{
/* we have the inode open somewhere else
no need to discard cache data */
goto
psx_client_can_cache
;
}
/* BB FIXME need to fix this check to move it earlier into posix_open
BB fIX following section BB FIXME */
/* if not oplocked, invalidate inode pages if mtime or file
size changed */
/* temp = cifs_NTtimeToUnix(le64_to_cpu(buf->LastWriteTime));
if (timespec_equal(&file->f_path.dentry->d_inode->i_mtime, &temp) &&
(file->f_path.dentry->d_inode->i_size ==
(loff_t)le64_to_cpu(buf->EndOfFile))) {
cFYI(1, ("inode unchanged on server"));
} else {
if (file->f_path.dentry->d_inode->i_mapping) {
rc = filemap_write_and_wait(file->f_path.dentry->d_inode->i_mapping);
if (rc != 0)
CIFS_I(file->f_path.dentry->d_inode)->write_behind_rc = rc;
}
cFYI(1, ("invalidating remote inode since open detected it "
"changed"));
invalidate_remote_inode(file->f_path.dentry->d_inode);
} */
psx_client_can_cache:
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
;
/* will have to change the unlock if we reenable the
filemap_fdatawrite (which does not seem necessary */
write_unlock
(
&
GlobalSMBSeslock
);
return
0
;
}
/* 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
,
struct
cifsInodeInfo
*
pCifsInode
,
struct
cifsFileInfo
*
pCifsFile
,
...
...
@@ -195,7 +269,7 @@ int cifs_open(struct inode *inode, struct file *file)
int
rc
=
-
EACCES
;
int
xid
,
oplock
;
struct
cifs_sb_info
*
cifs_sb
;
struct
cifsTconInfo
*
pT
con
;
struct
cifsTconInfo
*
t
con
;
struct
cifsFileInfo
*
pCifsFile
;
struct
cifsInodeInfo
*
pCifsInode
;
struct
list_head
*
tmp
;
...
...
@@ -208,7 +282,7 @@ int cifs_open(struct inode *inode, struct file *file)
xid
=
GetXid
();
cifs_sb
=
CIFS_SB
(
inode
->
i_sb
);
pT
con
=
cifs_sb
->
tcon
;
t
con
=
cifs_sb
->
tcon
;
if
(
file
->
f_flags
&
O_CREAT
)
{
/* search inode for this file and fill in file->private_data */
...
...
@@ -248,6 +322,35 @@ int cifs_open(struct inode *inode, struct file *file)
cFYI
(
1
,
(
"inode = 0x%p file flags are 0x%x for %s"
,
inode
,
file
->
f_flags
,
full_path
));
if
(
oplockEnabled
)
oplock
=
REQ_OPLOCK
;
else
oplock
=
0
;
if
(
tcon
->
unix_ext
&&
(
tcon
->
ses
->
capabilities
&
CAP_UNIX
)
&&
(
CIFS_UNIX_POSIX_PATH_OPS_CAP
&
le64_to_cpu
(
tcon
->
fsUnixInfo
.
Capability
)))
{
int
oflags
=
(
int
)
cifs_posix_convert_flags
(
file
->
f_flags
);
/* can not refresh inode info since size could be stale */
rc
=
cifs_posix_open
(
full_path
,
&
inode
,
inode
->
i_sb
,
cifs_sb
->
mnt_file_mode
/* ignored */
,
oflags
,
&
oplock
,
&
netfid
,
xid
);
if
(
rc
==
0
)
{
cFYI
(
1
,
(
"posix open succeeded"
));
/* no need for special case handling of setting mode
on read only files needed here */
cifs_posix_open_inode_helper
(
inode
,
file
,
pCifsInode
,
pCifsFile
,
oplock
,
netfid
);
goto
out
;
}
else
if
((
rc
!=
-
EIO
)
&&
(
rc
!=
-
EREMOTE
)
&&
(
rc
!=
-
EOPNOTSUPP
))
/* path not found or net err */
goto
out
;
/* fallthrough to retry open the old way on operation
not supported or DFS errors */
}
desiredAccess
=
cifs_convert_flags
(
file
->
f_flags
);
/*********************************************************************
...
...
@@ -276,11 +379,6 @@ int cifs_open(struct inode *inode, struct file *file)
disposition
=
cifs_get_disposition
(
file
->
f_flags
);
if
(
oplockEnabled
)
oplock
=
REQ_OPLOCK
;
else
oplock
=
0
;
/* BB pass O_SYNC flag through on file attributes .. BB */
/* Also refresh inode by passing in file_info buf returned by SMBOpen
...
...
@@ -297,7 +395,7 @@ int cifs_open(struct inode *inode, struct file *file)
}
if
(
cifs_sb
->
tcon
->
ses
->
capabilities
&
CAP_NT_SMBS
)
rc
=
CIFSSMBOpen
(
xid
,
pT
con
,
full_path
,
disposition
,
rc
=
CIFSSMBOpen
(
xid
,
t
con
,
full_path
,
disposition
,
desiredAccess
,
CREATE_NOT_DIR
,
&
netfid
,
&
oplock
,
buf
,
cifs_sb
->
local_nls
,
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_MAP_SPECIAL_CHR
);
...
...
@@ -306,7 +404,7 @@ int cifs_open(struct inode *inode, struct file *file)
if
(
rc
==
-
EIO
)
{
/* Old server, try legacy style OpenX */
rc
=
SMBLegacyOpen
(
xid
,
pT
con
,
full_path
,
disposition
,
rc
=
SMBLegacyOpen
(
xid
,
t
con
,
full_path
,
disposition
,
desiredAccess
,
CREATE_NOT_DIR
,
&
netfid
,
&
oplock
,
buf
,
cifs_sb
->
local_nls
,
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_MAP_SPECIAL_CHR
);
...
...
@@ -323,12 +421,12 @@ int cifs_open(struct inode *inode, struct file *file)
}
pCifsFile
=
cifs_init_private
(
file
->
private_data
,
inode
,
file
,
netfid
);
write_lock
(
&
GlobalSMBSeslock
);
list_add
(
&
pCifsFile
->
tlist
,
&
pT
con
->
openFileList
);
list_add
(
&
pCifsFile
->
tlist
,
&
t
con
->
openFileList
);
pCifsInode
=
CIFS_I
(
file
->
f_path
.
dentry
->
d_inode
);
if
(
pCifsInode
)
{
rc
=
cifs_open_inode_helper
(
inode
,
file
,
pCifsInode
,
pCifsFile
,
pT
con
,
pCifsFile
,
t
con
,
&
oplock
,
buf
,
full_path
,
xid
);
}
else
{
write_unlock
(
&
GlobalSMBSeslock
);
...
...
@@ -337,7 +435,7 @@ int cifs_open(struct inode *inode, struct file *file)
if
(
oplock
&
CIFS_CREATE_ACTION
)
{
/* time to set mode which we can not set earlier due to
problems creating new read-only files */
if
(
pT
con
->
unix_ext
)
{
if
(
t
con
->
unix_ext
)
{
struct
cifs_unix_set_info_args
args
=
{
.
mode
=
inode
->
i_mode
,
.
uid
=
NO_CHANGE_64
,
...
...
@@ -347,7 +445,7 @@ int cifs_open(struct inode *inode, struct file *file)
.
mtime
=
NO_CHANGE_64
,
.
device
=
0
,
};
CIFSSMBUnixSetInfo
(
xid
,
pT
con
,
full_path
,
&
args
,
CIFSSMBUnixSetInfo
(
xid
,
t
con
,
full_path
,
&
args
,
cifs_sb
->
local_nls
,
cifs_sb
->
mnt_cifs_flags
&
CIFS_MOUNT_MAP_SPECIAL_CHR
);
...
...
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