Loading fs/cifs/cifsfs.c +21 −7 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ #include <linux/kthread.h> #include <linux/freezer.h> #include <linux/namei.h> #include <linux/random.h> #include <net/ipv6.h> #include "cifsfs.h" #include "cifspdu.h" Loading Loading @@ -88,6 +89,10 @@ extern mempool_t *cifs_mid_poolp; struct workqueue_struct *cifsiod_wq; #ifdef CONFIG_CIFS_SMB2 __u8 cifs_client_guid[SMB2_CLIENT_GUID_SIZE]; #endif static int cifs_read_super(struct super_block *sb) { Loading Loading @@ -218,9 +223,10 @@ cifs_alloc_inode(struct super_block *sb) return NULL; cifs_inode->cifsAttrs = 0x20; /* default */ cifs_inode->time = 0; /* Until the file is open and we have gotten oplock info back from the server, can not assume caching of file data or metadata */ /* * Until the file is open and we have gotten oplock info back from the * server, can not assume caching of file data or metadata. */ cifs_set_oplock_level(cifs_inode, 0); cifs_inode->delete_pending = false; cifs_inode->invalid_mapping = false; Loading @@ -228,9 +234,13 @@ cifs_alloc_inode(struct super_block *sb) cifs_inode->server_eof = 0; cifs_inode->uniqueid = 0; cifs_inode->createtime = 0; /* Can not set i_flags here - they get immediately overwritten to zero by the VFS */ #ifdef CONFIG_CIFS_SMB2 get_random_bytes(cifs_inode->lease_key, SMB2_LEASE_KEY_SIZE); #endif /* * Can not set i_flags here - they get immediately overwritten to zero * by the VFS. */ /* cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME; */ INIT_LIST_HEAD(&cifs_inode->openFileList); INIT_LIST_HEAD(&cifs_inode->llist); Loading Loading @@ -1107,6 +1117,10 @@ init_cifs(void) spin_lock_init(&cifs_file_list_lock); spin_lock_init(&GlobalMid_Lock); #ifdef CONFIG_CIFS_SMB2 get_random_bytes(cifs_client_guid, SMB2_CLIENT_GUID_SIZE); #endif if (cifs_max_pending < 2) { cifs_max_pending = 2; cFYI(1, "cifs_max_pending set to min of 2"); Loading fs/cifs/cifsglob.h +10 −0 Original line number Diff line number Diff line Loading @@ -361,6 +361,12 @@ struct smb_version_operations { const unsigned int); /* push brlocks from the cache to the server */ int (*push_mand_locks)(struct cifsFileInfo *); /* get lease key of the inode */ void (*get_lease_key)(struct inode *, struct cifs_fid *fid); /* set lease key of the inode */ void (*set_lease_key)(struct inode *, struct cifs_fid *fid); /* generate new lease key */ void (*new_lease_key)(struct cifs_fid *fid); }; struct smb_version_values { Loading Loading @@ -895,6 +901,7 @@ struct cifs_fid { #ifdef CONFIG_CIFS_SMB2 __u64 persistent_fid; /* persist file id for smb2 */ __u64 volatile_fid; /* volatile file id for smb2 */ __u8 lease_key[SMB2_LEASE_KEY_SIZE]; /* lease key for smb2 */ #endif }; Loading Loading @@ -1012,6 +1019,9 @@ struct cifsInodeInfo { u64 server_eof; /* current file size on server -- protected by i_lock */ u64 uniqueid; /* server inode number */ u64 createtime; /* creation time on server */ #ifdef CONFIG_CIFS_SMB2 __u8 lease_key[SMB2_LEASE_KEY_SIZE]; /* lease key for this inode */ #endif #ifdef CONFIG_CIFS_FSCACHE struct fscache_cookie *fscache; #endif Loading fs/cifs/dir.c +11 −2 Original line number Diff line number Diff line Loading @@ -340,6 +340,8 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, rc = cifs_get_inode_info(&newinode, full_path, buf, inode->i_sb, xid, &fid->netfid); if (newinode) { if (server->ops->set_lease_key) server->ops->set_lease_key(newinode, fid); if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) newinode->i_mode = mode; if ((*oplock & CIFS_CREATE_ACTION) && Loading Loading @@ -418,6 +420,9 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, tcon = tlink_tcon(tlink); server = tcon->ses->server; if (server->ops->new_lease_key) server->ops->new_lease_key(&fid); rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, &oplock, &fid, opened); Loading Loading @@ -473,10 +478,14 @@ int cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode, if (IS_ERR(tlink)) goto out_free_xid; rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, &oplock, &fid, &created); tcon = tlink_tcon(tlink); server = tcon->ses->server; if (server->ops->new_lease_key) server->ops->new_lease_key(&fid); rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, &oplock, &fid, &created); if (!rc && server->ops->close) server->ops->close(xid, tcon, &fid); Loading fs/cifs/file.c +15 −6 Original line number Diff line number Diff line Loading @@ -177,8 +177,9 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb, int disposition; int create_options = CREATE_NOT_DIR; FILE_ALL_INFO *buf; struct TCP_Server_Info *server = tcon->ses->server; if (!tcon->ses->server->ops->open) if (!server->ops->open) return -ENOSYS; desired_access = cifs_convert_flags(f_flags); Loading Loading @@ -218,9 +219,9 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb, if (backup_cred(cifs_sb)) create_options |= CREATE_OPEN_BACKUP_INTENT; rc = tcon->ses->server->ops->open(xid, tcon, full_path, disposition, desired_access, create_options, fid, oplock, buf, cifs_sb); rc = server->ops->open(xid, tcon, full_path, disposition, desired_access, create_options, fid, oplock, buf, cifs_sb); if (rc) goto out; Loading Loading @@ -372,6 +373,7 @@ int cifs_open(struct inode *inode, struct file *file) unsigned int xid; __u32 oplock; struct cifs_sb_info *cifs_sb; struct TCP_Server_Info *server; struct cifs_tcon *tcon; struct tcon_link *tlink; struct cifsFileInfo *cfile = NULL; Loading @@ -388,6 +390,7 @@ int cifs_open(struct inode *inode, struct file *file) return PTR_ERR(tlink); } tcon = tlink_tcon(tlink); server = tcon->ses->server; full_path = build_path_from_dentry(file->f_path.dentry); if (full_path == NULL) { Loading Loading @@ -432,6 +435,9 @@ int cifs_open(struct inode *inode, struct file *file) } if (!posix_open_ok) { if (server->ops->get_lease_key) server->ops->get_lease_key(inode, &fid); rc = cifs_nt_open(full_path, inode, cifs_sb, tcon, file->f_flags, &oplock, &fid, xid); if (rc) Loading @@ -440,8 +446,8 @@ int cifs_open(struct inode *inode, struct file *file) cfile = cifs_new_fileinfo(&fid, file, tlink, oplock); if (cfile == NULL) { if (tcon->ses->server->ops->close) tcon->ses->server->ops->close(xid, tcon, &fid); if (server->ops->close) server->ops->close(xid, tcon, &fid); rc = -ENOMEM; goto out; } Loading Loading @@ -567,6 +573,9 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush) if (backup_cred(cifs_sb)) create_options |= CREATE_OPEN_BACKUP_INTENT; if (server->ops->get_lease_key) server->ops->get_lease_key(inode, &fid); /* * Can not refresh inode by passing in file_info buf to be returned by * CIFSSMBOpen and then calling get_inode_info with returned buf since Loading fs/cifs/smb2file.c +7 −2 Original line number Diff line number Diff line Loading @@ -63,6 +63,7 @@ smb2_open_file(const unsigned int xid, struct cifs_tcon *tcon, const char *path, int rc; __le16 *smb2_path; struct smb2_file_all_info *smb2_data = NULL; __u8 smb2_oplock[17]; smb2_path = cifs_convert_path_to_utf16(path, cifs_sb); if (smb2_path == NULL) { Loading @@ -78,11 +79,14 @@ smb2_open_file(const unsigned int xid, struct cifs_tcon *tcon, const char *path, } desired_access |= FILE_READ_ATTRIBUTES; *oplock = SMB2_OPLOCK_LEVEL_EXCLUSIVE; *smb2_oplock = SMB2_OPLOCK_LEVEL_EXCLUSIVE; if (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING) memcpy(smb2_oplock + 1, fid->lease_key, SMB2_LEASE_KEY_SIZE); rc = SMB2_open(xid, tcon, smb2_path, &fid->persistent_fid, &fid->volatile_fid, desired_access, disposition, 0, 0, (__u8 *)oplock, smb2_data); 0, 0, smb2_oplock, smb2_data); if (rc) goto out; Loading @@ -99,6 +103,7 @@ smb2_open_file(const unsigned int xid, struct cifs_tcon *tcon, const char *path, move_smb2_info_to_cifs(buf, smb2_data); } *oplock = *smb2_oplock; out: kfree(smb2_data); kfree(smb2_path); Loading Loading
fs/cifs/cifsfs.c +21 −7 Original line number Diff line number Diff line Loading @@ -36,6 +36,7 @@ #include <linux/kthread.h> #include <linux/freezer.h> #include <linux/namei.h> #include <linux/random.h> #include <net/ipv6.h> #include "cifsfs.h" #include "cifspdu.h" Loading Loading @@ -88,6 +89,10 @@ extern mempool_t *cifs_mid_poolp; struct workqueue_struct *cifsiod_wq; #ifdef CONFIG_CIFS_SMB2 __u8 cifs_client_guid[SMB2_CLIENT_GUID_SIZE]; #endif static int cifs_read_super(struct super_block *sb) { Loading Loading @@ -218,9 +223,10 @@ cifs_alloc_inode(struct super_block *sb) return NULL; cifs_inode->cifsAttrs = 0x20; /* default */ cifs_inode->time = 0; /* Until the file is open and we have gotten oplock info back from the server, can not assume caching of file data or metadata */ /* * Until the file is open and we have gotten oplock info back from the * server, can not assume caching of file data or metadata. */ cifs_set_oplock_level(cifs_inode, 0); cifs_inode->delete_pending = false; cifs_inode->invalid_mapping = false; Loading @@ -228,9 +234,13 @@ cifs_alloc_inode(struct super_block *sb) cifs_inode->server_eof = 0; cifs_inode->uniqueid = 0; cifs_inode->createtime = 0; /* Can not set i_flags here - they get immediately overwritten to zero by the VFS */ #ifdef CONFIG_CIFS_SMB2 get_random_bytes(cifs_inode->lease_key, SMB2_LEASE_KEY_SIZE); #endif /* * Can not set i_flags here - they get immediately overwritten to zero * by the VFS. */ /* cifs_inode->vfs_inode.i_flags = S_NOATIME | S_NOCMTIME; */ INIT_LIST_HEAD(&cifs_inode->openFileList); INIT_LIST_HEAD(&cifs_inode->llist); Loading Loading @@ -1107,6 +1117,10 @@ init_cifs(void) spin_lock_init(&cifs_file_list_lock); spin_lock_init(&GlobalMid_Lock); #ifdef CONFIG_CIFS_SMB2 get_random_bytes(cifs_client_guid, SMB2_CLIENT_GUID_SIZE); #endif if (cifs_max_pending < 2) { cifs_max_pending = 2; cFYI(1, "cifs_max_pending set to min of 2"); Loading
fs/cifs/cifsglob.h +10 −0 Original line number Diff line number Diff line Loading @@ -361,6 +361,12 @@ struct smb_version_operations { const unsigned int); /* push brlocks from the cache to the server */ int (*push_mand_locks)(struct cifsFileInfo *); /* get lease key of the inode */ void (*get_lease_key)(struct inode *, struct cifs_fid *fid); /* set lease key of the inode */ void (*set_lease_key)(struct inode *, struct cifs_fid *fid); /* generate new lease key */ void (*new_lease_key)(struct cifs_fid *fid); }; struct smb_version_values { Loading Loading @@ -895,6 +901,7 @@ struct cifs_fid { #ifdef CONFIG_CIFS_SMB2 __u64 persistent_fid; /* persist file id for smb2 */ __u64 volatile_fid; /* volatile file id for smb2 */ __u8 lease_key[SMB2_LEASE_KEY_SIZE]; /* lease key for smb2 */ #endif }; Loading Loading @@ -1012,6 +1019,9 @@ struct cifsInodeInfo { u64 server_eof; /* current file size on server -- protected by i_lock */ u64 uniqueid; /* server inode number */ u64 createtime; /* creation time on server */ #ifdef CONFIG_CIFS_SMB2 __u8 lease_key[SMB2_LEASE_KEY_SIZE]; /* lease key for this inode */ #endif #ifdef CONFIG_CIFS_FSCACHE struct fscache_cookie *fscache; #endif Loading
fs/cifs/dir.c +11 −2 Original line number Diff line number Diff line Loading @@ -340,6 +340,8 @@ cifs_do_create(struct inode *inode, struct dentry *direntry, unsigned int xid, rc = cifs_get_inode_info(&newinode, full_path, buf, inode->i_sb, xid, &fid->netfid); if (newinode) { if (server->ops->set_lease_key) server->ops->set_lease_key(newinode, fid); if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) newinode->i_mode = mode; if ((*oplock & CIFS_CREATE_ACTION) && Loading Loading @@ -418,6 +420,9 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, tcon = tlink_tcon(tlink); server = tcon->ses->server; if (server->ops->new_lease_key) server->ops->new_lease_key(&fid); rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, &oplock, &fid, opened); Loading Loading @@ -473,10 +478,14 @@ int cifs_create(struct inode *inode, struct dentry *direntry, umode_t mode, if (IS_ERR(tlink)) goto out_free_xid; rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, &oplock, &fid, &created); tcon = tlink_tcon(tlink); server = tcon->ses->server; if (server->ops->new_lease_key) server->ops->new_lease_key(&fid); rc = cifs_do_create(inode, direntry, xid, tlink, oflags, mode, &oplock, &fid, &created); if (!rc && server->ops->close) server->ops->close(xid, tcon, &fid); Loading
fs/cifs/file.c +15 −6 Original line number Diff line number Diff line Loading @@ -177,8 +177,9 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb, int disposition; int create_options = CREATE_NOT_DIR; FILE_ALL_INFO *buf; struct TCP_Server_Info *server = tcon->ses->server; if (!tcon->ses->server->ops->open) if (!server->ops->open) return -ENOSYS; desired_access = cifs_convert_flags(f_flags); Loading Loading @@ -218,9 +219,9 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb, if (backup_cred(cifs_sb)) create_options |= CREATE_OPEN_BACKUP_INTENT; rc = tcon->ses->server->ops->open(xid, tcon, full_path, disposition, desired_access, create_options, fid, oplock, buf, cifs_sb); rc = server->ops->open(xid, tcon, full_path, disposition, desired_access, create_options, fid, oplock, buf, cifs_sb); if (rc) goto out; Loading Loading @@ -372,6 +373,7 @@ int cifs_open(struct inode *inode, struct file *file) unsigned int xid; __u32 oplock; struct cifs_sb_info *cifs_sb; struct TCP_Server_Info *server; struct cifs_tcon *tcon; struct tcon_link *tlink; struct cifsFileInfo *cfile = NULL; Loading @@ -388,6 +390,7 @@ int cifs_open(struct inode *inode, struct file *file) return PTR_ERR(tlink); } tcon = tlink_tcon(tlink); server = tcon->ses->server; full_path = build_path_from_dentry(file->f_path.dentry); if (full_path == NULL) { Loading Loading @@ -432,6 +435,9 @@ int cifs_open(struct inode *inode, struct file *file) } if (!posix_open_ok) { if (server->ops->get_lease_key) server->ops->get_lease_key(inode, &fid); rc = cifs_nt_open(full_path, inode, cifs_sb, tcon, file->f_flags, &oplock, &fid, xid); if (rc) Loading @@ -440,8 +446,8 @@ int cifs_open(struct inode *inode, struct file *file) cfile = cifs_new_fileinfo(&fid, file, tlink, oplock); if (cfile == NULL) { if (tcon->ses->server->ops->close) tcon->ses->server->ops->close(xid, tcon, &fid); if (server->ops->close) server->ops->close(xid, tcon, &fid); rc = -ENOMEM; goto out; } Loading Loading @@ -567,6 +573,9 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush) if (backup_cred(cifs_sb)) create_options |= CREATE_OPEN_BACKUP_INTENT; if (server->ops->get_lease_key) server->ops->get_lease_key(inode, &fid); /* * Can not refresh inode by passing in file_info buf to be returned by * CIFSSMBOpen and then calling get_inode_info with returned buf since Loading
fs/cifs/smb2file.c +7 −2 Original line number Diff line number Diff line Loading @@ -63,6 +63,7 @@ smb2_open_file(const unsigned int xid, struct cifs_tcon *tcon, const char *path, int rc; __le16 *smb2_path; struct smb2_file_all_info *smb2_data = NULL; __u8 smb2_oplock[17]; smb2_path = cifs_convert_path_to_utf16(path, cifs_sb); if (smb2_path == NULL) { Loading @@ -78,11 +79,14 @@ smb2_open_file(const unsigned int xid, struct cifs_tcon *tcon, const char *path, } desired_access |= FILE_READ_ATTRIBUTES; *oplock = SMB2_OPLOCK_LEVEL_EXCLUSIVE; *smb2_oplock = SMB2_OPLOCK_LEVEL_EXCLUSIVE; if (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING) memcpy(smb2_oplock + 1, fid->lease_key, SMB2_LEASE_KEY_SIZE); rc = SMB2_open(xid, tcon, smb2_path, &fid->persistent_fid, &fid->volatile_fid, desired_access, disposition, 0, 0, (__u8 *)oplock, smb2_data); 0, 0, smb2_oplock, smb2_data); if (rc) goto out; Loading @@ -99,6 +103,7 @@ smb2_open_file(const unsigned int xid, struct cifs_tcon *tcon, const char *path, move_smb2_info_to_cifs(buf, smb2_data); } *oplock = *smb2_oplock; out: kfree(smb2_data); kfree(smb2_path); Loading