Loading fs/cifs/cifsglob.h +1 −0 Original line number Diff line number Diff line Loading @@ -907,6 +907,7 @@ cap_unix(struct cifs_ses *ses) struct cached_fid { bool is_valid:1; /* Do we have a useable root fid */ struct kref refcount; struct cifs_fid *fid; struct mutex fid_mutex; struct cifs_tcon *tcon; Loading fs/cifs/smb2inode.c +3 −1 Original line number Diff line number Diff line Loading @@ -120,7 +120,9 @@ smb2_open_op_close(const unsigned int xid, struct cifs_tcon *tcon, break; } if (use_cached_root_handle == false) if (use_cached_root_handle) close_shroot(&tcon->crfid); else rc = SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); if (tmprc) rc = tmprc; Loading fs/cifs/smb2ops.c +26 −5 Original line number Diff line number Diff line Loading @@ -470,21 +470,36 @@ SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon) return rc; } void smb2_cached_lease_break(struct work_struct *work) static void smb2_close_cached_fid(struct kref *ref) { struct cached_fid *cfid = container_of(work, struct cached_fid, lease_break); mutex_lock(&cfid->fid_mutex); struct cached_fid *cfid = container_of(ref, struct cached_fid, refcount); if (cfid->is_valid) { cifs_dbg(FYI, "clear cached root file handle\n"); SMB2_close(0, cfid->tcon, cfid->fid->persistent_fid, cfid->fid->volatile_fid); cfid->is_valid = false; } } void close_shroot(struct cached_fid *cfid) { mutex_lock(&cfid->fid_mutex); kref_put(&cfid->refcount, smb2_close_cached_fid); mutex_unlock(&cfid->fid_mutex); } void smb2_cached_lease_break(struct work_struct *work) { struct cached_fid *cfid = container_of(work, struct cached_fid, lease_break); close_shroot(cfid); } /* * Open the directory at the root of a share */ Loading @@ -499,6 +514,7 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid *pfid) if (tcon->crfid.is_valid) { cifs_dbg(FYI, "found a cached root file handle\n"); memcpy(pfid, tcon->crfid.fid, sizeof(struct cifs_fid)); kref_get(&tcon->crfid.refcount); mutex_unlock(&tcon->crfid.fid_mutex); return 0; } Loading @@ -515,6 +531,8 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid *pfid) memcpy(tcon->crfid.fid, pfid, sizeof(struct cifs_fid)); tcon->crfid.tcon = tcon; tcon->crfid.is_valid = true; kref_init(&tcon->crfid.refcount); kref_get(&tcon->crfid.refcount); } mutex_unlock(&tcon->crfid.fid_mutex); return rc; Loading Loading @@ -558,6 +576,9 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon) FS_SECTOR_SIZE_INFORMATION); /* SMB3 specific */ if (no_cached_open) SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); else close_shroot(&tcon->crfid); return; } Loading fs/cifs/smb2proto.h +1 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ extern int smb3_handle_read_data(struct TCP_Server_Info *server, extern int open_shroot(unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid *pfid); extern void close_shroot(struct cached_fid *cfid); extern void move_smb2_info_to_cifs(FILE_ALL_INFO *dst, struct smb2_file_all_info *src); extern int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, Loading Loading
fs/cifs/cifsglob.h +1 −0 Original line number Diff line number Diff line Loading @@ -907,6 +907,7 @@ cap_unix(struct cifs_ses *ses) struct cached_fid { bool is_valid:1; /* Do we have a useable root fid */ struct kref refcount; struct cifs_fid *fid; struct mutex fid_mutex; struct cifs_tcon *tcon; Loading
fs/cifs/smb2inode.c +3 −1 Original line number Diff line number Diff line Loading @@ -120,7 +120,9 @@ smb2_open_op_close(const unsigned int xid, struct cifs_tcon *tcon, break; } if (use_cached_root_handle == false) if (use_cached_root_handle) close_shroot(&tcon->crfid); else rc = SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); if (tmprc) rc = tmprc; Loading
fs/cifs/smb2ops.c +26 −5 Original line number Diff line number Diff line Loading @@ -470,21 +470,36 @@ SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon) return rc; } void smb2_cached_lease_break(struct work_struct *work) static void smb2_close_cached_fid(struct kref *ref) { struct cached_fid *cfid = container_of(work, struct cached_fid, lease_break); mutex_lock(&cfid->fid_mutex); struct cached_fid *cfid = container_of(ref, struct cached_fid, refcount); if (cfid->is_valid) { cifs_dbg(FYI, "clear cached root file handle\n"); SMB2_close(0, cfid->tcon, cfid->fid->persistent_fid, cfid->fid->volatile_fid); cfid->is_valid = false; } } void close_shroot(struct cached_fid *cfid) { mutex_lock(&cfid->fid_mutex); kref_put(&cfid->refcount, smb2_close_cached_fid); mutex_unlock(&cfid->fid_mutex); } void smb2_cached_lease_break(struct work_struct *work) { struct cached_fid *cfid = container_of(work, struct cached_fid, lease_break); close_shroot(cfid); } /* * Open the directory at the root of a share */ Loading @@ -499,6 +514,7 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid *pfid) if (tcon->crfid.is_valid) { cifs_dbg(FYI, "found a cached root file handle\n"); memcpy(pfid, tcon->crfid.fid, sizeof(struct cifs_fid)); kref_get(&tcon->crfid.refcount); mutex_unlock(&tcon->crfid.fid_mutex); return 0; } Loading @@ -515,6 +531,8 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid *pfid) memcpy(tcon->crfid.fid, pfid, sizeof(struct cifs_fid)); tcon->crfid.tcon = tcon; tcon->crfid.is_valid = true; kref_init(&tcon->crfid.refcount); kref_get(&tcon->crfid.refcount); } mutex_unlock(&tcon->crfid.fid_mutex); return rc; Loading Loading @@ -558,6 +576,9 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon) FS_SECTOR_SIZE_INFORMATION); /* SMB3 specific */ if (no_cached_open) SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid); else close_shroot(&tcon->crfid); return; } Loading
fs/cifs/smb2proto.h +1 −0 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ extern int smb3_handle_read_data(struct TCP_Server_Info *server, extern int open_shroot(unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid *pfid); extern void close_shroot(struct cached_fid *cfid); extern void move_smb2_info_to_cifs(FILE_ALL_INFO *dst, struct smb2_file_all_info *src); extern int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, Loading