Commit 25364138 authored by Pavel Shilovsky's avatar Pavel Shilovsky Committed by Steve French

CIFS: Move create code use ops struct

Signed-off-by: default avatarPavel Shilovsky <pshilovsky@samba.org>
Signed-off-by: default avatarSteve French <smfrench@gmail.com>
parent b7546bc5
...@@ -160,17 +160,18 @@ check_name(struct dentry *direntry) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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);
......
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