Commit df60cee2 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag '6.7-rc3-smb3-server-fixes' of git://git.samba.org/ksmbd

Pull smb server fixes from Steve French:

 - Memory leak fix

 - Fix possible deadlock in open

 - Multiple SMB3 leasing (caching) fixes including:
     - incorrect open count (found via xfstest generic/002 with leases)
     - lease breaking incorrect serialization
     - lease break error handling fix
     - fix sending async response when lease pending

 - Async command fix

* tag '6.7-rc3-smb3-server-fixes' of git://git.samba.org/ksmbd:
  ksmbd: don't update ->op_state as OPLOCK_STATE_NONE on error
  ksmbd: move setting SMB2_FLAGS_ASYNC_COMMAND and AsyncId
  ksmbd: release interim response after sending status pending response
  ksmbd: move oplock handling after unlock parent dir
  ksmbd: separately allocate ci per dentry
  ksmbd: fix possible deadlock in smb2_open
  ksmbd: prevent memory leak on error return
parents d095b18f cd80ce7e
...@@ -56,6 +56,9 @@ void ksmbd_free_work_struct(struct ksmbd_work *work) ...@@ -56,6 +56,9 @@ void ksmbd_free_work_struct(struct ksmbd_work *work)
kfree(work->tr_buf); kfree(work->tr_buf);
kvfree(work->request_buf); kvfree(work->request_buf);
kfree(work->iov); kfree(work->iov);
if (!list_empty(&work->interim_entry))
list_del(&work->interim_entry);
if (work->async_id) if (work->async_id)
ksmbd_release_id(&work->conn->async_ida, work->async_id); ksmbd_release_id(&work->conn->async_ida, work->async_id);
kmem_cache_free(work_cache, work); kmem_cache_free(work_cache, work);
...@@ -106,7 +109,7 @@ static inline void __ksmbd_iov_pin(struct ksmbd_work *work, void *ib, ...@@ -106,7 +109,7 @@ static inline void __ksmbd_iov_pin(struct ksmbd_work *work, void *ib,
static int __ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len, static int __ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len,
void *aux_buf, unsigned int aux_size) void *aux_buf, unsigned int aux_size)
{ {
struct aux_read *ar; struct aux_read *ar = NULL;
int need_iov_cnt = 1; int need_iov_cnt = 1;
if (aux_size) { if (aux_size) {
...@@ -123,8 +126,11 @@ static int __ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len, ...@@ -123,8 +126,11 @@ static int __ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len,
new = krealloc(work->iov, new = krealloc(work->iov,
sizeof(struct kvec) * work->iov_alloc_cnt, sizeof(struct kvec) * work->iov_alloc_cnt,
GFP_KERNEL | __GFP_ZERO); GFP_KERNEL | __GFP_ZERO);
if (!new) if (!new) {
kfree(ar);
work->iov_alloc_cnt -= 4;
return -ENOMEM; return -ENOMEM;
}
work->iov = new; work->iov = new;
} }
......
...@@ -833,7 +833,8 @@ static int smb2_lease_break_noti(struct oplock_info *opinfo) ...@@ -833,7 +833,8 @@ static int smb2_lease_break_noti(struct oplock_info *opinfo)
interim_entry); interim_entry);
setup_async_work(in_work, NULL, NULL); setup_async_work(in_work, NULL, NULL);
smb2_send_interim_resp(in_work, STATUS_PENDING); smb2_send_interim_resp(in_work, STATUS_PENDING);
list_del(&in_work->interim_entry); list_del_init(&in_work->interim_entry);
release_async_work(in_work);
} }
INIT_WORK(&work->work, __smb2_lease_break_noti); INIT_WORK(&work->work, __smb2_lease_break_noti);
ksmbd_queue_work(work); ksmbd_queue_work(work);
......
This diff is collapsed.
...@@ -1185,7 +1185,7 @@ int smb_inherit_dacl(struct ksmbd_conn *conn, ...@@ -1185,7 +1185,7 @@ int smb_inherit_dacl(struct ksmbd_conn *conn,
pntsd_size += sizeof(struct smb_acl) + nt_size; pntsd_size += sizeof(struct smb_acl) + nt_size;
} }
ksmbd_vfs_set_sd_xattr(conn, idmap, path, pntsd, pntsd_size); ksmbd_vfs_set_sd_xattr(conn, idmap, path, pntsd, pntsd_size, false);
kfree(pntsd); kfree(pntsd);
} }
...@@ -1377,7 +1377,7 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path, ...@@ -1377,7 +1377,7 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path,
int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
const struct path *path, struct smb_ntsd *pntsd, int ntsd_len, const struct path *path, struct smb_ntsd *pntsd, int ntsd_len,
bool type_check) bool type_check, bool get_write)
{ {
int rc; int rc;
struct smb_fattr fattr = {{0}}; struct smb_fattr fattr = {{0}};
...@@ -1437,7 +1437,8 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, ...@@ -1437,7 +1437,8 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
if (test_share_config_flag(tcon->share_conf, KSMBD_SHARE_FLAG_ACL_XATTR)) { if (test_share_config_flag(tcon->share_conf, KSMBD_SHARE_FLAG_ACL_XATTR)) {
/* Update WinACL in xattr */ /* Update WinACL in xattr */
ksmbd_vfs_remove_sd_xattrs(idmap, path); ksmbd_vfs_remove_sd_xattrs(idmap, path);
ksmbd_vfs_set_sd_xattr(conn, idmap, path, pntsd, ntsd_len); ksmbd_vfs_set_sd_xattr(conn, idmap, path, pntsd, ntsd_len,
get_write);
} }
out: out:
......
...@@ -207,7 +207,7 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path, ...@@ -207,7 +207,7 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, const struct path *path,
__le32 *pdaccess, int uid); __le32 *pdaccess, int uid);
int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon, int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
const struct path *path, struct smb_ntsd *pntsd, int ntsd_len, const struct path *path, struct smb_ntsd *pntsd, int ntsd_len,
bool type_check); bool type_check, bool get_write);
void id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid); void id_to_sid(unsigned int cid, uint sidtype, struct smb_sid *ssid);
void ksmbd_init_domain(u32 *sub_auth); void ksmbd_init_domain(u32 *sub_auth);
......
...@@ -97,6 +97,13 @@ static int ksmbd_vfs_path_lookup_locked(struct ksmbd_share_config *share_conf, ...@@ -97,6 +97,13 @@ static int ksmbd_vfs_path_lookup_locked(struct ksmbd_share_config *share_conf,
return -ENOENT; return -ENOENT;
} }
err = mnt_want_write(parent_path->mnt);
if (err) {
path_put(parent_path);
putname(filename);
return -ENOENT;
}
inode_lock_nested(parent_path->dentry->d_inode, I_MUTEX_PARENT); inode_lock_nested(parent_path->dentry->d_inode, I_MUTEX_PARENT);
d = lookup_one_qstr_excl(&last, parent_path->dentry, 0); d = lookup_one_qstr_excl(&last, parent_path->dentry, 0);
if (IS_ERR(d)) if (IS_ERR(d))
...@@ -123,6 +130,7 @@ static int ksmbd_vfs_path_lookup_locked(struct ksmbd_share_config *share_conf, ...@@ -123,6 +130,7 @@ static int ksmbd_vfs_path_lookup_locked(struct ksmbd_share_config *share_conf,
err_out: err_out:
inode_unlock(d_inode(parent_path->dentry)); inode_unlock(d_inode(parent_path->dentry));
mnt_drop_write(parent_path->mnt);
path_put(parent_path); path_put(parent_path);
putname(filename); putname(filename);
return -ENOENT; return -ENOENT;
...@@ -451,7 +459,8 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos, ...@@ -451,7 +459,8 @@ static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos,
fp->stream.name, fp->stream.name,
(void *)stream_buf, (void *)stream_buf,
size, size,
0); 0,
true);
if (err < 0) if (err < 0)
goto out; goto out;
...@@ -593,10 +602,6 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, const struct path *path) ...@@ -593,10 +602,6 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, const struct path *path)
goto out_err; goto out_err;
} }
err = mnt_want_write(path->mnt);
if (err)
goto out_err;
idmap = mnt_idmap(path->mnt); idmap = mnt_idmap(path->mnt);
if (S_ISDIR(d_inode(path->dentry)->i_mode)) { if (S_ISDIR(d_inode(path->dentry)->i_mode)) {
err = vfs_rmdir(idmap, d_inode(parent), path->dentry); err = vfs_rmdir(idmap, d_inode(parent), path->dentry);
...@@ -607,7 +612,6 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, const struct path *path) ...@@ -607,7 +612,6 @@ int ksmbd_vfs_remove_file(struct ksmbd_work *work, const struct path *path)
if (err) if (err)
ksmbd_debug(VFS, "unlink failed, err %d\n", err); ksmbd_debug(VFS, "unlink failed, err %d\n", err);
} }
mnt_drop_write(path->mnt);
out_err: out_err:
ksmbd_revert_fsids(work); ksmbd_revert_fsids(work);
...@@ -715,7 +719,7 @@ int ksmbd_vfs_rename(struct ksmbd_work *work, const struct path *old_path, ...@@ -715,7 +719,7 @@ int ksmbd_vfs_rename(struct ksmbd_work *work, const struct path *old_path,
goto out3; goto out3;
} }
parent_fp = ksmbd_lookup_fd_inode(d_inode(old_child->d_parent)); parent_fp = ksmbd_lookup_fd_inode(old_child->d_parent);
if (parent_fp) { if (parent_fp) {
if (parent_fp->daccess & FILE_DELETE_LE) { if (parent_fp->daccess & FILE_DELETE_LE) {
pr_err("parent dir is opened with delete access\n"); pr_err("parent dir is opened with delete access\n");
...@@ -907,18 +911,22 @@ ssize_t ksmbd_vfs_getxattr(struct mnt_idmap *idmap, ...@@ -907,18 +911,22 @@ ssize_t ksmbd_vfs_getxattr(struct mnt_idmap *idmap,
* @attr_value: xattr value to set * @attr_value: xattr value to set
* @attr_size: size of xattr value * @attr_size: size of xattr value
* @flags: destination buffer length * @flags: destination buffer length
* @get_write: get write access to a mount
* *
* Return: 0 on success, otherwise error * Return: 0 on success, otherwise error
*/ */
int ksmbd_vfs_setxattr(struct mnt_idmap *idmap, int ksmbd_vfs_setxattr(struct mnt_idmap *idmap,
const struct path *path, const char *attr_name, const struct path *path, const char *attr_name,
void *attr_value, size_t attr_size, int flags) void *attr_value, size_t attr_size, int flags,
bool get_write)
{ {
int err; int err;
if (get_write == true) {
err = mnt_want_write(path->mnt); err = mnt_want_write(path->mnt);
if (err) if (err)
return err; return err;
}
err = vfs_setxattr(idmap, err = vfs_setxattr(idmap,
path->dentry, path->dentry,
...@@ -928,6 +936,7 @@ int ksmbd_vfs_setxattr(struct mnt_idmap *idmap, ...@@ -928,6 +936,7 @@ int ksmbd_vfs_setxattr(struct mnt_idmap *idmap,
flags); flags);
if (err) if (err)
ksmbd_debug(VFS, "setxattr failed, err %d\n", err); ksmbd_debug(VFS, "setxattr failed, err %d\n", err);
if (get_write == true)
mnt_drop_write(path->mnt); mnt_drop_write(path->mnt);
return err; return err;
} }
...@@ -1252,6 +1261,13 @@ int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name, ...@@ -1252,6 +1261,13 @@ int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name,
} }
if (!err) { if (!err) {
err = mnt_want_write(parent_path->mnt);
if (err) {
path_put(path);
path_put(parent_path);
return err;
}
err = ksmbd_vfs_lock_parent(parent_path->dentry, path->dentry); err = ksmbd_vfs_lock_parent(parent_path->dentry, path->dentry);
if (err) { if (err) {
path_put(path); path_put(path);
...@@ -1261,6 +1277,14 @@ int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name, ...@@ -1261,6 +1277,14 @@ int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name,
return err; return err;
} }
void ksmbd_vfs_kern_path_unlock(struct path *parent_path, struct path *path)
{
inode_unlock(d_inode(parent_path->dentry));
mnt_drop_write(parent_path->mnt);
path_put(path);
path_put(parent_path);
}
struct dentry *ksmbd_vfs_kern_path_create(struct ksmbd_work *work, struct dentry *ksmbd_vfs_kern_path_create(struct ksmbd_work *work,
const char *name, const char *name,
unsigned int flags, unsigned int flags,
...@@ -1415,7 +1439,8 @@ static struct xattr_smb_acl *ksmbd_vfs_make_xattr_posix_acl(struct mnt_idmap *id ...@@ -1415,7 +1439,8 @@ static struct xattr_smb_acl *ksmbd_vfs_make_xattr_posix_acl(struct mnt_idmap *id
int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn,
struct mnt_idmap *idmap, struct mnt_idmap *idmap,
const struct path *path, const struct path *path,
struct smb_ntsd *pntsd, int len) struct smb_ntsd *pntsd, int len,
bool get_write)
{ {
int rc; int rc;
struct ndr sd_ndr = {0}, acl_ndr = {0}; struct ndr sd_ndr = {0}, acl_ndr = {0};
...@@ -1475,7 +1500,7 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, ...@@ -1475,7 +1500,7 @@ int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn,
rc = ksmbd_vfs_setxattr(idmap, path, rc = ksmbd_vfs_setxattr(idmap, path,
XATTR_NAME_SD, sd_ndr.data, XATTR_NAME_SD, sd_ndr.data,
sd_ndr.offset, 0); sd_ndr.offset, 0, get_write);
if (rc < 0) if (rc < 0)
pr_err("Failed to store XATTR ntacl :%d\n", rc); pr_err("Failed to store XATTR ntacl :%d\n", rc);
...@@ -1564,7 +1589,8 @@ int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn, ...@@ -1564,7 +1589,8 @@ int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn,
int ksmbd_vfs_set_dos_attrib_xattr(struct mnt_idmap *idmap, int ksmbd_vfs_set_dos_attrib_xattr(struct mnt_idmap *idmap,
const struct path *path, const struct path *path,
struct xattr_dos_attrib *da) struct xattr_dos_attrib *da,
bool get_write)
{ {
struct ndr n; struct ndr n;
int err; int err;
...@@ -1574,7 +1600,7 @@ int ksmbd_vfs_set_dos_attrib_xattr(struct mnt_idmap *idmap, ...@@ -1574,7 +1600,7 @@ int ksmbd_vfs_set_dos_attrib_xattr(struct mnt_idmap *idmap,
return err; return err;
err = ksmbd_vfs_setxattr(idmap, path, XATTR_NAME_DOS_ATTRIBUTE, err = ksmbd_vfs_setxattr(idmap, path, XATTR_NAME_DOS_ATTRIBUTE,
(void *)n.data, n.offset, 0); (void *)n.data, n.offset, 0, get_write);
if (err) if (err)
ksmbd_debug(SMB, "failed to store dos attribute in xattr\n"); ksmbd_debug(SMB, "failed to store dos attribute in xattr\n");
kfree(n.data); kfree(n.data);
...@@ -1846,10 +1872,6 @@ int ksmbd_vfs_set_init_posix_acl(struct mnt_idmap *idmap, ...@@ -1846,10 +1872,6 @@ int ksmbd_vfs_set_init_posix_acl(struct mnt_idmap *idmap,
} }
posix_state_to_acl(&acl_state, acls->a_entries); posix_state_to_acl(&acl_state, acls->a_entries);
rc = mnt_want_write(path->mnt);
if (rc)
goto out_err;
rc = set_posix_acl(idmap, dentry, ACL_TYPE_ACCESS, acls); rc = set_posix_acl(idmap, dentry, ACL_TYPE_ACCESS, acls);
if (rc < 0) if (rc < 0)
ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n", ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n",
...@@ -1861,9 +1883,7 @@ int ksmbd_vfs_set_init_posix_acl(struct mnt_idmap *idmap, ...@@ -1861,9 +1883,7 @@ int ksmbd_vfs_set_init_posix_acl(struct mnt_idmap *idmap,
ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n", ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n",
rc); rc);
} }
mnt_drop_write(path->mnt);
out_err:
free_acl_state(&acl_state); free_acl_state(&acl_state);
posix_acl_release(acls); posix_acl_release(acls);
return rc; return rc;
...@@ -1893,10 +1913,6 @@ int ksmbd_vfs_inherit_posix_acl(struct mnt_idmap *idmap, ...@@ -1893,10 +1913,6 @@ int ksmbd_vfs_inherit_posix_acl(struct mnt_idmap *idmap,
} }
} }
rc = mnt_want_write(path->mnt);
if (rc)
goto out_err;
rc = set_posix_acl(idmap, dentry, ACL_TYPE_ACCESS, acls); rc = set_posix_acl(idmap, dentry, ACL_TYPE_ACCESS, acls);
if (rc < 0) if (rc < 0)
ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n", ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n",
...@@ -1908,9 +1924,7 @@ int ksmbd_vfs_inherit_posix_acl(struct mnt_idmap *idmap, ...@@ -1908,9 +1924,7 @@ int ksmbd_vfs_inherit_posix_acl(struct mnt_idmap *idmap,
ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n", ksmbd_debug(SMB, "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n",
rc); rc);
} }
mnt_drop_write(path->mnt);
out_err:
posix_acl_release(acls); posix_acl_release(acls);
return rc; return rc;
} }
...@@ -109,7 +109,8 @@ ssize_t ksmbd_vfs_casexattr_len(struct mnt_idmap *idmap, ...@@ -109,7 +109,8 @@ ssize_t ksmbd_vfs_casexattr_len(struct mnt_idmap *idmap,
int attr_name_len); int attr_name_len);
int ksmbd_vfs_setxattr(struct mnt_idmap *idmap, int ksmbd_vfs_setxattr(struct mnt_idmap *idmap,
const struct path *path, const char *attr_name, const struct path *path, const char *attr_name,
void *attr_value, size_t attr_size, int flags); void *attr_value, size_t attr_size, int flags,
bool get_write);
int ksmbd_vfs_xattr_stream_name(char *stream_name, char **xattr_stream_name, int ksmbd_vfs_xattr_stream_name(char *stream_name, char **xattr_stream_name,
size_t *xattr_stream_name_size, int s_type); size_t *xattr_stream_name_size, int s_type);
int ksmbd_vfs_remove_xattr(struct mnt_idmap *idmap, int ksmbd_vfs_remove_xattr(struct mnt_idmap *idmap,
...@@ -117,6 +118,7 @@ int ksmbd_vfs_remove_xattr(struct mnt_idmap *idmap, ...@@ -117,6 +118,7 @@ int ksmbd_vfs_remove_xattr(struct mnt_idmap *idmap,
int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name, int ksmbd_vfs_kern_path_locked(struct ksmbd_work *work, char *name,
unsigned int flags, struct path *parent_path, unsigned int flags, struct path *parent_path,
struct path *path, bool caseless); struct path *path, bool caseless);
void ksmbd_vfs_kern_path_unlock(struct path *parent_path, struct path *path);
struct dentry *ksmbd_vfs_kern_path_create(struct ksmbd_work *work, struct dentry *ksmbd_vfs_kern_path_create(struct ksmbd_work *work,
const char *name, const char *name,
unsigned int flags, unsigned int flags,
...@@ -144,14 +146,16 @@ int ksmbd_vfs_remove_sd_xattrs(struct mnt_idmap *idmap, const struct path *path) ...@@ -144,14 +146,16 @@ int ksmbd_vfs_remove_sd_xattrs(struct mnt_idmap *idmap, const struct path *path)
int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn, int ksmbd_vfs_set_sd_xattr(struct ksmbd_conn *conn,
struct mnt_idmap *idmap, struct mnt_idmap *idmap,
const struct path *path, const struct path *path,
struct smb_ntsd *pntsd, int len); struct smb_ntsd *pntsd, int len,
bool get_write);
int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn, int ksmbd_vfs_get_sd_xattr(struct ksmbd_conn *conn,
struct mnt_idmap *idmap, struct mnt_idmap *idmap,
struct dentry *dentry, struct dentry *dentry,
struct smb_ntsd **pntsd); struct smb_ntsd **pntsd);
int ksmbd_vfs_set_dos_attrib_xattr(struct mnt_idmap *idmap, int ksmbd_vfs_set_dos_attrib_xattr(struct mnt_idmap *idmap,
const struct path *path, const struct path *path,
struct xattr_dos_attrib *da); struct xattr_dos_attrib *da,
bool get_write);
int ksmbd_vfs_get_dos_attrib_xattr(struct mnt_idmap *idmap, int ksmbd_vfs_get_dos_attrib_xattr(struct mnt_idmap *idmap,
struct dentry *dentry, struct dentry *dentry,
struct xattr_dos_attrib *da); struct xattr_dos_attrib *da);
......
...@@ -66,14 +66,14 @@ static unsigned long inode_hash(struct super_block *sb, unsigned long hashval) ...@@ -66,14 +66,14 @@ static unsigned long inode_hash(struct super_block *sb, unsigned long hashval)
return tmp & inode_hash_mask; return tmp & inode_hash_mask;
} }
static struct ksmbd_inode *__ksmbd_inode_lookup(struct inode *inode) static struct ksmbd_inode *__ksmbd_inode_lookup(struct dentry *de)
{ {
struct hlist_head *head = inode_hashtable + struct hlist_head *head = inode_hashtable +
inode_hash(inode->i_sb, inode->i_ino); inode_hash(d_inode(de)->i_sb, (unsigned long)de);
struct ksmbd_inode *ci = NULL, *ret_ci = NULL; struct ksmbd_inode *ci = NULL, *ret_ci = NULL;
hlist_for_each_entry(ci, head, m_hash) { hlist_for_each_entry(ci, head, m_hash) {
if (ci->m_inode == inode) { if (ci->m_de == de) {
if (atomic_inc_not_zero(&ci->m_count)) if (atomic_inc_not_zero(&ci->m_count))
ret_ci = ci; ret_ci = ci;
break; break;
...@@ -84,26 +84,16 @@ static struct ksmbd_inode *__ksmbd_inode_lookup(struct inode *inode) ...@@ -84,26 +84,16 @@ static struct ksmbd_inode *__ksmbd_inode_lookup(struct inode *inode)
static struct ksmbd_inode *ksmbd_inode_lookup(struct ksmbd_file *fp) static struct ksmbd_inode *ksmbd_inode_lookup(struct ksmbd_file *fp)
{ {
return __ksmbd_inode_lookup(file_inode(fp->filp)); return __ksmbd_inode_lookup(fp->filp->f_path.dentry);
} }
static struct ksmbd_inode *ksmbd_inode_lookup_by_vfsinode(struct inode *inode) int ksmbd_query_inode_status(struct dentry *dentry)
{
struct ksmbd_inode *ci;
read_lock(&inode_hash_lock);
ci = __ksmbd_inode_lookup(inode);
read_unlock(&inode_hash_lock);
return ci;
}
int ksmbd_query_inode_status(struct inode *inode)
{ {
struct ksmbd_inode *ci; struct ksmbd_inode *ci;
int ret = KSMBD_INODE_STATUS_UNKNOWN; int ret = KSMBD_INODE_STATUS_UNKNOWN;
read_lock(&inode_hash_lock); read_lock(&inode_hash_lock);
ci = __ksmbd_inode_lookup(inode); ci = __ksmbd_inode_lookup(dentry);
if (ci) { if (ci) {
ret = KSMBD_INODE_STATUS_OK; ret = KSMBD_INODE_STATUS_OK;
if (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS)) if (ci->m_flags & (S_DEL_PENDING | S_DEL_ON_CLS))
...@@ -143,7 +133,7 @@ void ksmbd_fd_set_delete_on_close(struct ksmbd_file *fp, ...@@ -143,7 +133,7 @@ void ksmbd_fd_set_delete_on_close(struct ksmbd_file *fp,
static void ksmbd_inode_hash(struct ksmbd_inode *ci) static void ksmbd_inode_hash(struct ksmbd_inode *ci)
{ {
struct hlist_head *b = inode_hashtable + struct hlist_head *b = inode_hashtable +
inode_hash(ci->m_inode->i_sb, ci->m_inode->i_ino); inode_hash(d_inode(ci->m_de)->i_sb, (unsigned long)ci->m_de);
hlist_add_head(&ci->m_hash, b); hlist_add_head(&ci->m_hash, b);
} }
...@@ -157,7 +147,6 @@ static void ksmbd_inode_unhash(struct ksmbd_inode *ci) ...@@ -157,7 +147,6 @@ static void ksmbd_inode_unhash(struct ksmbd_inode *ci)
static int ksmbd_inode_init(struct ksmbd_inode *ci, struct ksmbd_file *fp) static int ksmbd_inode_init(struct ksmbd_inode *ci, struct ksmbd_file *fp)
{ {
ci->m_inode = file_inode(fp->filp);
atomic_set(&ci->m_count, 1); atomic_set(&ci->m_count, 1);
atomic_set(&ci->op_count, 0); atomic_set(&ci->op_count, 0);
atomic_set(&ci->sop_count, 0); atomic_set(&ci->sop_count, 0);
...@@ -166,6 +155,7 @@ static int ksmbd_inode_init(struct ksmbd_inode *ci, struct ksmbd_file *fp) ...@@ -166,6 +155,7 @@ static int ksmbd_inode_init(struct ksmbd_inode *ci, struct ksmbd_file *fp)
INIT_LIST_HEAD(&ci->m_fp_list); INIT_LIST_HEAD(&ci->m_fp_list);
INIT_LIST_HEAD(&ci->m_op_list); INIT_LIST_HEAD(&ci->m_op_list);
rwlock_init(&ci->m_lock); rwlock_init(&ci->m_lock);
ci->m_de = fp->filp->f_path.dentry;
return 0; return 0;
} }
...@@ -488,12 +478,15 @@ struct ksmbd_file *ksmbd_lookup_fd_cguid(char *cguid) ...@@ -488,12 +478,15 @@ struct ksmbd_file *ksmbd_lookup_fd_cguid(char *cguid)
return fp; return fp;
} }
struct ksmbd_file *ksmbd_lookup_fd_inode(struct inode *inode) struct ksmbd_file *ksmbd_lookup_fd_inode(struct dentry *dentry)
{ {
struct ksmbd_file *lfp; struct ksmbd_file *lfp;
struct ksmbd_inode *ci; struct ksmbd_inode *ci;
struct inode *inode = d_inode(dentry);
ci = ksmbd_inode_lookup_by_vfsinode(inode); read_lock(&inode_hash_lock);
ci = __ksmbd_inode_lookup(dentry);
read_unlock(&inode_hash_lock);
if (!ci) if (!ci)
return NULL; return NULL;
......
...@@ -51,7 +51,7 @@ struct ksmbd_inode { ...@@ -51,7 +51,7 @@ struct ksmbd_inode {
atomic_t op_count; atomic_t op_count;
/* opinfo count for streams */ /* opinfo count for streams */
atomic_t sop_count; atomic_t sop_count;
struct inode *m_inode; struct dentry *m_de;
unsigned int m_flags; unsigned int m_flags;
struct hlist_node m_hash; struct hlist_node m_hash;
struct list_head m_fp_list; struct list_head m_fp_list;
...@@ -140,7 +140,7 @@ struct ksmbd_file *ksmbd_lookup_fd_slow(struct ksmbd_work *work, u64 id, ...@@ -140,7 +140,7 @@ struct ksmbd_file *ksmbd_lookup_fd_slow(struct ksmbd_work *work, u64 id,
void ksmbd_fd_put(struct ksmbd_work *work, struct ksmbd_file *fp); void ksmbd_fd_put(struct ksmbd_work *work, struct ksmbd_file *fp);
struct ksmbd_file *ksmbd_lookup_durable_fd(unsigned long long id); struct ksmbd_file *ksmbd_lookup_durable_fd(unsigned long long id);
struct ksmbd_file *ksmbd_lookup_fd_cguid(char *cguid); struct ksmbd_file *ksmbd_lookup_fd_cguid(char *cguid);
struct ksmbd_file *ksmbd_lookup_fd_inode(struct inode *inode); struct ksmbd_file *ksmbd_lookup_fd_inode(struct dentry *dentry);
unsigned int ksmbd_open_durable_fd(struct ksmbd_file *fp); unsigned int ksmbd_open_durable_fd(struct ksmbd_file *fp);
struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp); struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp);
void ksmbd_close_tree_conn_fds(struct ksmbd_work *work); void ksmbd_close_tree_conn_fds(struct ksmbd_work *work);
...@@ -164,7 +164,7 @@ enum KSMBD_INODE_STATUS { ...@@ -164,7 +164,7 @@ enum KSMBD_INODE_STATUS {
KSMBD_INODE_STATUS_PENDING_DELETE, KSMBD_INODE_STATUS_PENDING_DELETE,
}; };
int ksmbd_query_inode_status(struct inode *inode); int ksmbd_query_inode_status(struct dentry *dentry);
bool ksmbd_inode_pending_delete(struct ksmbd_file *fp); bool ksmbd_inode_pending_delete(struct ksmbd_file *fp);
void ksmbd_set_inode_pending_delete(struct ksmbd_file *fp); void ksmbd_set_inode_pending_delete(struct ksmbd_file *fp);
void ksmbd_clear_inode_pending_delete(struct ksmbd_file *fp); void ksmbd_clear_inode_pending_delete(struct ksmbd_file *fp);
......
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