CIFS: Move create code use ops struct
Signed-off-by: Pavel Shilovsky <pshilovsky@samba.org> Signed-off-by: Steve French <smfrench@gmail.com>
This commit is contained in:
parent
b7546bc54c
commit
253641388a
@ -160,17 +160,18 @@ check_name(struct dentry *direntry)
|
|||||||
static int
|
static int
|
||||||
cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
|
cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
|
||||||
struct tcon_link *tlink, unsigned oflags, umode_t mode,
|
struct tcon_link *tlink, unsigned oflags, umode_t mode,
|
||||||
__u32 *oplock, __u16 *fileHandle, int *created)
|
__u32 *oplock, struct cifs_fid *fid, int *created)
|
||||||
{
|
{
|
||||||
int rc = -ENOENT;
|
int rc = -ENOENT;
|
||||||
int create_options = CREATE_NOT_DIR;
|
int create_options = CREATE_NOT_DIR;
|
||||||
int desiredAccess;
|
int desired_access;
|
||||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||||
struct cifs_tcon *tcon = tlink_tcon(tlink);
|
struct cifs_tcon *tcon = tlink_tcon(tlink);
|
||||||
char *full_path = NULL;
|
char *full_path = NULL;
|
||||||
FILE_ALL_INFO *buf = NULL;
|
FILE_ALL_INFO *buf = NULL;
|
||||||
struct inode *newinode = NULL;
|
struct inode *newinode = NULL;
|
||||||
int disposition;
|
int disposition;
|
||||||
|
struct TCP_Server_Info *server = tcon->ses->server;
|
||||||
|
|
||||||
*oplock = 0;
|
*oplock = 0;
|
||||||
if (tcon->ses->server->oplocks)
|
if (tcon->ses->server->oplocks)
|
||||||
@ -185,8 +186,8 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
|
|||||||
if (tcon->unix_ext && cap_unix(tcon->ses) && !tcon->broken_posix_open &&
|
if (tcon->unix_ext && cap_unix(tcon->ses) && !tcon->broken_posix_open &&
|
||||||
(CIFS_UNIX_POSIX_PATH_OPS_CAP &
|
(CIFS_UNIX_POSIX_PATH_OPS_CAP &
|
||||||
le64_to_cpu(tcon->fsUnixInfo.Capability))) {
|
le64_to_cpu(tcon->fsUnixInfo.Capability))) {
|
||||||
rc = cifs_posix_open(full_path, &newinode,
|
rc = cifs_posix_open(full_path, &newinode, inode->i_sb, mode,
|
||||||
inode->i_sb, mode, oflags, oplock, fileHandle, xid);
|
oflags, oplock, &fid->netfid, xid);
|
||||||
switch (rc) {
|
switch (rc) {
|
||||||
case 0:
|
case 0:
|
||||||
if (newinode == NULL) {
|
if (newinode == NULL) {
|
||||||
@ -202,7 +203,7 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
|
|||||||
* close it and proceed as if it were a normal
|
* close it and proceed as if it were a normal
|
||||||
* lookup.
|
* lookup.
|
||||||
*/
|
*/
|
||||||
CIFSSMBClose(xid, tcon, *fileHandle);
|
CIFSSMBClose(xid, tcon, fid->netfid);
|
||||||
goto cifs_create_get_file_info;
|
goto cifs_create_get_file_info;
|
||||||
}
|
}
|
||||||
/* success, no need to query */
|
/* success, no need to query */
|
||||||
@ -244,11 +245,11 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
desiredAccess = 0;
|
desired_access = 0;
|
||||||
if (OPEN_FMODE(oflags) & FMODE_READ)
|
if (OPEN_FMODE(oflags) & FMODE_READ)
|
||||||
desiredAccess |= GENERIC_READ; /* is this too little? */
|
desired_access |= GENERIC_READ; /* is this too little? */
|
||||||
if (OPEN_FMODE(oflags) & FMODE_WRITE)
|
if (OPEN_FMODE(oflags) & FMODE_WRITE)
|
||||||
desiredAccess |= GENERIC_WRITE;
|
desired_access |= GENERIC_WRITE;
|
||||||
|
|
||||||
disposition = FILE_OVERWRITE_IF;
|
disposition = FILE_OVERWRITE_IF;
|
||||||
if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
|
if ((oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL))
|
||||||
@ -260,8 +261,15 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
|
|||||||
else
|
else
|
||||||
cFYI(1, "Create flag not set in create function");
|
cFYI(1, "Create flag not set in create function");
|
||||||
|
|
||||||
/* BB add processing to set equivalent of mode - e.g. via CreateX with
|
/*
|
||||||
ACLs */
|
* BB add processing to set equivalent of mode - e.g. via CreateX with
|
||||||
|
* ACLs
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!server->ops->open) {
|
||||||
|
rc = -ENOSYS;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
|
buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
@ -279,28 +287,18 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
|
|||||||
if (backup_cred(cifs_sb))
|
if (backup_cred(cifs_sb))
|
||||||
create_options |= CREATE_OPEN_BACKUP_INTENT;
|
create_options |= CREATE_OPEN_BACKUP_INTENT;
|
||||||
|
|
||||||
if (tcon->ses->capabilities & CAP_NT_SMBS)
|
rc = server->ops->open(xid, tcon, full_path, disposition,
|
||||||
rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
|
desired_access, create_options, fid, oplock,
|
||||||
desiredAccess, create_options,
|
buf, cifs_sb);
|
||||||
fileHandle, oplock, buf, cifs_sb->local_nls,
|
|
||||||
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
|
|
||||||
else
|
|
||||||
rc = -EIO; /* no NT SMB support fall into legacy open below */
|
|
||||||
|
|
||||||
if (rc == -EIO) {
|
|
||||||
/* old server, retry the open legacy style */
|
|
||||||
rc = SMBLegacyOpen(xid, tcon, full_path, disposition,
|
|
||||||
desiredAccess, create_options,
|
|
||||||
fileHandle, oplock, buf, cifs_sb->local_nls,
|
|
||||||
cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
|
|
||||||
}
|
|
||||||
if (rc) {
|
if (rc) {
|
||||||
cFYI(1, "cifs_create returned 0x%x", rc);
|
cFYI(1, "cifs_create returned 0x%x", rc);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If Open reported that we actually created a file
|
/*
|
||||||
then we now have to set the mode if possible */
|
* If Open reported that we actually created a file then we now have to
|
||||||
|
* set the mode if possible.
|
||||||
|
*/
|
||||||
if ((tcon->unix_ext) && (*oplock & CIFS_CREATE_ACTION)) {
|
if ((tcon->unix_ext) && (*oplock & CIFS_CREATE_ACTION)) {
|
||||||
struct cifs_unix_set_info_args args = {
|
struct cifs_unix_set_info_args args = {
|
||||||
.mode = mode,
|
.mode = mode,
|
||||||
@ -321,11 +319,13 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
|
|||||||
args.uid = NO_CHANGE_64;
|
args.uid = NO_CHANGE_64;
|
||||||
args.gid = NO_CHANGE_64;
|
args.gid = NO_CHANGE_64;
|
||||||
}
|
}
|
||||||
CIFSSMBUnixSetFileInfo(xid, tcon, &args, *fileHandle,
|
CIFSSMBUnixSetFileInfo(xid, tcon, &args, fid->netfid,
|
||||||
current->tgid);
|
current->tgid);
|
||||||
} else {
|
} else {
|
||||||
/* BB implement mode setting via Windows security
|
/*
|
||||||
descriptors e.g. */
|
* BB implement mode setting via Windows security
|
||||||
|
* descriptors e.g.
|
||||||
|
*/
|
||||||
/* CIFSSMBWinSetPerms(xid,tcon,path,mode,-1,-1,nls);*/
|
/* CIFSSMBWinSetPerms(xid,tcon,path,mode,-1,-1,nls);*/
|
||||||
|
|
||||||
/* Could set r/o dos attribute if mode & 0222 == 0 */
|
/* Could set r/o dos attribute if mode & 0222 == 0 */
|
||||||
@ -334,11 +334,11 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
|
|||||||
cifs_create_get_file_info:
|
cifs_create_get_file_info:
|
||||||
/* server might mask mode so we have to query for it */
|
/* server might mask mode so we have to query for it */
|
||||||
if (tcon->unix_ext)
|
if (tcon->unix_ext)
|
||||||
rc = cifs_get_inode_info_unix(&newinode, full_path,
|
rc = cifs_get_inode_info_unix(&newinode, full_path, inode->i_sb,
|
||||||
inode->i_sb, xid);
|
xid);
|
||||||
else {
|
else {
|
||||||
rc = cifs_get_inode_info(&newinode, full_path, buf,
|
rc = cifs_get_inode_info(&newinode, full_path, buf, inode->i_sb,
|
||||||
inode->i_sb, xid, fileHandle);
|
xid, &fid->netfid);
|
||||||
if (newinode) {
|
if (newinode) {
|
||||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
|
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
|
||||||
newinode->i_mode = mode;
|
newinode->i_mode = mode;
|
||||||
@ -356,7 +356,8 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid,
|
|||||||
cifs_create_set_dentry:
|
cifs_create_set_dentry:
|
||||||
if (rc != 0) {
|
if (rc != 0) {
|
||||||
cFYI(1, "Create worked, get_inode_info failed rc = %d", rc);
|
cFYI(1, "Create worked, get_inode_info failed rc = %d", rc);
|
||||||
CIFSSMBClose(xid, tcon, *fileHandle);
|
if (server->ops->close)
|
||||||
|
server->ops->close(xid, tcon, fid);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
d_drop(direntry);
|
d_drop(direntry);
|
||||||
@ -377,6 +378,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
|
|||||||
unsigned int xid;
|
unsigned int xid;
|
||||||
struct tcon_link *tlink;
|
struct tcon_link *tlink;
|
||||||
struct cifs_tcon *tcon;
|
struct cifs_tcon *tcon;
|
||||||
|
struct TCP_Server_Info *server;
|
||||||
struct cifs_fid fid;
|
struct cifs_fid fid;
|
||||||
__u32 oplock;
|
__u32 oplock;
|
||||||
struct cifsFileInfo *file_info;
|
struct cifsFileInfo *file_info;
|
||||||
@ -414,22 +416,25 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
|
|||||||
goto out_free_xid;
|
goto out_free_xid;
|
||||||
|
|
||||||
tcon = tlink_tcon(tlink);
|
tcon = tlink_tcon(tlink);
|
||||||
|
server = tcon->ses->server;
|
||||||
|
|
||||||
rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode,
|
rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode,
|
||||||
&oplock, &fid.netfid, opened);
|
&oplock, &fid, opened);
|
||||||
|
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
rc = finish_open(file, direntry, generic_file_open, opened);
|
rc = finish_open(file, direntry, generic_file_open, opened);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
CIFSSMBClose(xid, tcon, fid.netfid);
|
if (server->ops->close)
|
||||||
|
server->ops->close(xid, tcon, &fid);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
file_info = cifs_new_fileinfo(&fid, file, tlink, oplock);
|
file_info = cifs_new_fileinfo(&fid, file, tlink, oplock);
|
||||||
if (file_info == NULL) {
|
if (file_info == NULL) {
|
||||||
CIFSSMBClose(xid, tcon, fid.netfid);
|
if (server->ops->close)
|
||||||
|
server->ops->close(xid, tcon, &fid);
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,7 +459,9 @@ int cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
|
|||||||
*/
|
*/
|
||||||
unsigned oflags = O_EXCL | O_CREAT | O_RDWR;
|
unsigned oflags = O_EXCL | O_CREAT | O_RDWR;
|
||||||
struct tcon_link *tlink;
|
struct tcon_link *tlink;
|
||||||
__u16 fileHandle;
|
struct cifs_tcon *tcon;
|
||||||
|
struct TCP_Server_Info *server;
|
||||||
|
struct cifs_fid fid;
|
||||||
__u32 oplock;
|
__u32 oplock;
|
||||||
int created = FILE_CREATED;
|
int created = FILE_CREATED;
|
||||||
|
|
||||||
@ -467,9 +474,11 @@ int cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode,
|
|||||||
goto out_free_xid;
|
goto out_free_xid;
|
||||||
|
|
||||||
rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode,
|
rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode,
|
||||||
&oplock, &fileHandle, &created);
|
&oplock, &fid, &created);
|
||||||
if (!rc)
|
tcon = tlink_tcon(tlink);
|
||||||
CIFSSMBClose(xid, tlink_tcon(tlink), fileHandle);
|
server = tcon->ses->server;
|
||||||
|
if (!rc && server->ops->close)
|
||||||
|
server->ops->close(xid, tcon, &fid);
|
||||||
|
|
||||||
cifs_put_tlink(tlink);
|
cifs_put_tlink(tlink);
|
||||||
out_free_xid:
|
out_free_xid:
|
||||||
|
@ -312,13 +312,13 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file)
|
|||||||
if (list_empty(&cifsi->openFileList)) {
|
if (list_empty(&cifsi->openFileList)) {
|
||||||
cFYI(1, "closing last open instance for inode %p",
|
cFYI(1, "closing last open instance for inode %p",
|
||||||
cifs_file->dentry->d_inode);
|
cifs_file->dentry->d_inode);
|
||||||
|
/*
|
||||||
/* in strict cache mode we need invalidate mapping on the last
|
* In strict cache mode we need invalidate mapping on the last
|
||||||
close because it may cause a error when we open this file
|
* close because it may cause a error when we open this file
|
||||||
again and get at least level II oplock */
|
* again and get at least level II oplock.
|
||||||
|
*/
|
||||||
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO)
|
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO)
|
||||||
CIFS_I(inode)->invalid_mapping = true;
|
CIFS_I(inode)->invalid_mapping = true;
|
||||||
|
|
||||||
cifs_set_oplock_level(cifsi, 0);
|
cifs_set_oplock_level(cifsi, 0);
|
||||||
}
|
}
|
||||||
spin_unlock(&cifs_file_list_lock);
|
spin_unlock(&cifs_file_list_lock);
|
||||||
|
@ -622,7 +622,7 @@ cifs_open_file(const unsigned int xid, struct cifs_tcon *tcon, const char *path,
|
|||||||
{
|
{
|
||||||
if (!(tcon->ses->capabilities & CAP_NT_SMBS))
|
if (!(tcon->ses->capabilities & CAP_NT_SMBS))
|
||||||
return SMBLegacyOpen(xid, tcon, path, disposition,
|
return SMBLegacyOpen(xid, tcon, path, disposition,
|
||||||
desired_access, CREATE_NOT_DIR,
|
desired_access, create_options,
|
||||||
&fid->netfid, oplock, buf,
|
&fid->netfid, oplock, buf,
|
||||||
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
|
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
|
||||||
& CIFS_MOUNT_MAP_SPECIAL_CHR);
|
& CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||||
|
Loading…
Reference in New Issue
Block a user