mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-16 05:50:19 +00:00
CIFS: Simplify non-posix open stuff (try #2)
Delete cifs_open_inode_helper and move non-posix open related things to cifs_nt_open function. Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Pavel Shilovsky <piastryyy@gmail.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
This commit is contained in:
parent
4b886136df
commit
eeb910a6d4
189
fs/cifs/file.c
189
fs/cifs/file.c
@ -104,53 +104,6 @@ static inline int cifs_get_disposition(unsigned int flags)
|
||||
return FILE_OPEN;
|
||||
}
|
||||
|
||||
static inline int cifs_open_inode_helper(struct inode *inode,
|
||||
struct cifsTconInfo *pTcon, __u32 oplock, FILE_ALL_INFO *buf,
|
||||
char *full_path, int xid)
|
||||
{
|
||||
struct cifsInodeInfo *pCifsInode = CIFS_I(inode);
|
||||
struct timespec temp;
|
||||
int rc;
|
||||
|
||||
if (pCifsInode->clientCanCacheRead) {
|
||||
/* we have the inode open somewhere else
|
||||
no need to discard cache data */
|
||||
goto client_can_cache;
|
||||
}
|
||||
|
||||
/* BB need same check in cifs_create too? */
|
||||
/* if not oplocked, invalidate inode pages if mtime or file
|
||||
size changed */
|
||||
temp = cifs_NTtimeToUnix(buf->LastWriteTime);
|
||||
if (timespec_equal(&inode->i_mtime, &temp) &&
|
||||
(inode->i_size ==
|
||||
(loff_t)le64_to_cpu(buf->EndOfFile))) {
|
||||
cFYI(1, "inode unchanged on server");
|
||||
} else {
|
||||
if (inode->i_mapping) {
|
||||
/* BB no need to lock inode until after invalidate
|
||||
since namei code should already have it locked? */
|
||||
rc = filemap_write_and_wait(inode->i_mapping);
|
||||
mapping_set_error(inode->i_mapping, rc);
|
||||
}
|
||||
cFYI(1, "invalidating remote inode since open detected it "
|
||||
"changed");
|
||||
invalidate_remote_inode(inode);
|
||||
}
|
||||
|
||||
client_can_cache:
|
||||
if (pTcon->unix_ext)
|
||||
rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb,
|
||||
xid);
|
||||
else
|
||||
rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb,
|
||||
xid, NULL);
|
||||
|
||||
cifs_set_oplock_level(pCifsInode, oplock);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cifs_posix_open(char *full_path, struct inode **pinode,
|
||||
struct super_block *sb, int mode, unsigned int f_flags,
|
||||
__u32 *poplock, __u16 *pnetfid, int xid)
|
||||
@ -213,6 +166,76 @@ posix_open_ret:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
|
||||
struct cifsTconInfo *tcon, unsigned int f_flags, __u32 *poplock,
|
||||
__u16 *pnetfid, int xid)
|
||||
{
|
||||
int rc;
|
||||
int desiredAccess;
|
||||
int disposition;
|
||||
FILE_ALL_INFO *buf;
|
||||
|
||||
desiredAccess = cifs_convert_flags(f_flags);
|
||||
|
||||
/*********************************************************************
|
||||
* open flag mapping table:
|
||||
*
|
||||
* POSIX Flag CIFS Disposition
|
||||
* ---------- ----------------
|
||||
* O_CREAT FILE_OPEN_IF
|
||||
* O_CREAT | O_EXCL FILE_CREATE
|
||||
* O_CREAT | O_TRUNC FILE_OVERWRITE_IF
|
||||
* O_TRUNC FILE_OVERWRITE
|
||||
* none of the above FILE_OPEN
|
||||
*
|
||||
* Note that there is not a direct match between disposition
|
||||
* FILE_SUPERSEDE (ie create whether or not file exists although
|
||||
* O_CREAT | O_TRUNC is similar but truncates the existing
|
||||
* file rather than creating a new file as FILE_SUPERSEDE does
|
||||
* (which uses the attributes / metadata passed in on open call)
|
||||
*?
|
||||
*? O_SYNC is a reasonable match to CIFS writethrough flag
|
||||
*? and the read write flags match reasonably. O_LARGEFILE
|
||||
*? is irrelevant because largefile support is always used
|
||||
*? by this client. Flags O_APPEND, O_DIRECT, O_DIRECTORY,
|
||||
* O_FASYNC, O_NOFOLLOW, O_NONBLOCK need further investigation
|
||||
*********************************************************************/
|
||||
|
||||
disposition = cifs_get_disposition(f_flags);
|
||||
|
||||
/* BB pass O_SYNC flag through on file attributes .. BB */
|
||||
|
||||
buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
|
||||
if (tcon->ses->capabilities & CAP_NT_SMBS)
|
||||
rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
|
||||
desiredAccess, CREATE_NOT_DIR, pnetfid, poplock, buf,
|
||||
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
|
||||
& CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||
else
|
||||
rc = SMBLegacyOpen(xid, tcon, full_path, disposition,
|
||||
desiredAccess, CREATE_NOT_DIR, pnetfid, poplock, buf,
|
||||
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
|
||||
& CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
if (tcon->unix_ext)
|
||||
rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb,
|
||||
xid);
|
||||
else
|
||||
rc = cifs_get_inode_info(&inode, full_path, buf, inode->i_sb,
|
||||
xid, pnetfid);
|
||||
|
||||
out:
|
||||
kfree(buf);
|
||||
return rc;
|
||||
}
|
||||
|
||||
struct cifsFileInfo *
|
||||
cifs_new_fileinfo(__u16 fileHandle, struct file *file,
|
||||
struct tcon_link *tlink, __u32 oplock)
|
||||
@ -317,10 +340,7 @@ int cifs_open(struct inode *inode, struct file *file)
|
||||
struct cifsFileInfo *pCifsFile = NULL;
|
||||
struct cifsInodeInfo *pCifsInode;
|
||||
char *full_path = NULL;
|
||||
int desiredAccess;
|
||||
int disposition;
|
||||
__u16 netfid;
|
||||
FILE_ALL_INFO *buf = NULL;
|
||||
|
||||
xid = GetXid();
|
||||
|
||||
@ -385,71 +405,9 @@ int cifs_open(struct inode *inode, struct file *file)
|
||||
or DFS errors */
|
||||
}
|
||||
|
||||
desiredAccess = cifs_convert_flags(file->f_flags);
|
||||
|
||||
/*********************************************************************
|
||||
* open flag mapping table:
|
||||
*
|
||||
* POSIX Flag CIFS Disposition
|
||||
* ---------- ----------------
|
||||
* O_CREAT FILE_OPEN_IF
|
||||
* O_CREAT | O_EXCL FILE_CREATE
|
||||
* O_CREAT | O_TRUNC FILE_OVERWRITE_IF
|
||||
* O_TRUNC FILE_OVERWRITE
|
||||
* none of the above FILE_OPEN
|
||||
*
|
||||
* Note that there is not a direct match between disposition
|
||||
* FILE_SUPERSEDE (ie create whether or not file exists although
|
||||
* O_CREAT | O_TRUNC is similar but truncates the existing
|
||||
* file rather than creating a new file as FILE_SUPERSEDE does
|
||||
* (which uses the attributes / metadata passed in on open call)
|
||||
*?
|
||||
*? O_SYNC is a reasonable match to CIFS writethrough flag
|
||||
*? and the read write flags match reasonably. O_LARGEFILE
|
||||
*? is irrelevant because largefile support is always used
|
||||
*? by this client. Flags O_APPEND, O_DIRECT, O_DIRECTORY,
|
||||
* O_FASYNC, O_NOFOLLOW, O_NONBLOCK need further investigation
|
||||
*********************************************************************/
|
||||
|
||||
disposition = cifs_get_disposition(file->f_flags);
|
||||
|
||||
/* BB pass O_SYNC flag through on file attributes .. BB */
|
||||
|
||||
/* Also refresh inode by passing in file_info buf returned by SMBOpen
|
||||
and calling get_inode_info with returned buf (at least helps
|
||||
non-Unix server case) */
|
||||
|
||||
/* BB we can not do this if this is the second open of a file
|
||||
and the first handle has writebehind data, we might be
|
||||
able to simply do a filemap_fdatawrite/filemap_fdatawait first */
|
||||
buf = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
|
||||
if (!buf) {
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (tcon->ses->capabilities & CAP_NT_SMBS)
|
||||
rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
|
||||
desiredAccess, CREATE_NOT_DIR, &netfid, &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, try legacy style OpenX */
|
||||
rc = SMBLegacyOpen(xid, tcon, full_path, disposition,
|
||||
desiredAccess, CREATE_NOT_DIR, &netfid, &oplock, buf,
|
||||
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
|
||||
& CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||
}
|
||||
if (rc) {
|
||||
cFYI(1, "cifs_open returned 0x%x", rc);
|
||||
goto out;
|
||||
}
|
||||
|
||||
rc = cifs_open_inode_helper(inode, tcon, oplock, buf, full_path, xid);
|
||||
if (rc != 0)
|
||||
rc = cifs_nt_open(full_path, inode, cifs_sb, tcon, file->f_flags,
|
||||
&oplock, &netfid, xid);
|
||||
if (rc)
|
||||
goto out;
|
||||
|
||||
pCifsFile = cifs_new_fileinfo(netfid, file, tlink, oplock);
|
||||
@ -481,7 +439,6 @@ int cifs_open(struct inode *inode, struct file *file)
|
||||
}
|
||||
|
||||
out:
|
||||
kfree(buf);
|
||||
kfree(full_path);
|
||||
FreeXid(xid);
|
||||
cifs_put_tlink(tlink);
|
||||
|
Loading…
Reference in New Issue
Block a user