Skip to content

Commit 4274a9d

Browse files
namjaejeonsmfrench
authored andcommitted
ksmbd: separately allocate ci per dentry
xfstests generic/002 test fail when enabling smb2 leases feature. This test create hard link file, but removeal failed. ci has a file open count to count file open through the smb client, but in the case of hard link files, The allocation of ci per inode cause incorrectly open count for file deletion. This patch allocate ci per dentry to counts open counts for hard link. Signed-off-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Steve French <stfrench@microsoft.com>
1 parent 864fb5d commit 4274a9d

4 files changed

Lines changed: 18 additions & 25 deletions

File tree

fs/smb/server/smb2pdu.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3039,7 +3039,7 @@ int smb2_open(struct ksmbd_work *work)
30393039
}
30403040
}
30413041

3042-
rc = ksmbd_query_inode_status(d_inode(path.dentry->d_parent));
3042+
rc = ksmbd_query_inode_status(path.dentry->d_parent);
30433043
if (rc == KSMBD_INODE_STATUS_PENDING_DELETE) {
30443044
rc = -EBUSY;
30453045
goto err_out;

fs/smb/server/vfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -719,7 +719,7 @@ int ksmbd_vfs_rename(struct ksmbd_work *work, const struct path *old_path,
719719
goto out3;
720720
}
721721

722-
parent_fp = ksmbd_lookup_fd_inode(d_inode(old_child->d_parent));
722+
parent_fp = ksmbd_lookup_fd_inode(old_child->d_parent);
723723
if (parent_fp) {
724724
if (parent_fp->daccess & FILE_DELETE_LE) {
725725
pr_err("parent dir is opened with delete access\n");

fs/smb/server/vfs_cache.c

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -66,14 +66,14 @@ static unsigned long inode_hash(struct super_block *sb, unsigned long hashval)
6666
return tmp & inode_hash_mask;
6767
}
6868

69-
static struct ksmbd_inode *__ksmbd_inode_lookup(struct inode *inode)
69+
static struct ksmbd_inode *__ksmbd_inode_lookup(struct dentry *de)
7070
{
7171
struct hlist_head *head = inode_hashtable +
72-
inode_hash(inode->i_sb, inode->i_ino);
72+
inode_hash(d_inode(de)->i_sb, (unsigned long)de);
7373
struct ksmbd_inode *ci = NULL, *ret_ci = NULL;
7474

7575
hlist_for_each_entry(ci, head, m_hash) {
76-
if (ci->m_inode == inode) {
76+
if (ci->m_de == de) {
7777
if (atomic_inc_not_zero(&ci->m_count))
7878
ret_ci = ci;
7979
break;
@@ -84,26 +84,16 @@ static struct ksmbd_inode *__ksmbd_inode_lookup(struct inode *inode)
8484

8585
static struct ksmbd_inode *ksmbd_inode_lookup(struct ksmbd_file *fp)
8686
{
87-
return __ksmbd_inode_lookup(file_inode(fp->filp));
87+
return __ksmbd_inode_lookup(fp->filp->f_path.dentry);
8888
}
8989

90-
static struct ksmbd_inode *ksmbd_inode_lookup_by_vfsinode(struct inode *inode)
91-
{
92-
struct ksmbd_inode *ci;
93-
94-
read_lock(&inode_hash_lock);
95-
ci = __ksmbd_inode_lookup(inode);
96-
read_unlock(&inode_hash_lock);
97-
return ci;
98-
}
99-
100-
int ksmbd_query_inode_status(struct inode *inode)
90+
int ksmbd_query_inode_status(struct dentry *dentry)
10191
{
10292
struct ksmbd_inode *ci;
10393
int ret = KSMBD_INODE_STATUS_UNKNOWN;
10494

10595
read_lock(&inode_hash_lock);
106-
ci = __ksmbd_inode_lookup(inode);
96+
ci = __ksmbd_inode_lookup(dentry);
10797
if (ci) {
10898
ret = KSMBD_INODE_STATUS_OK;
10999
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,
143133
static void ksmbd_inode_hash(struct ksmbd_inode *ci)
144134
{
145135
struct hlist_head *b = inode_hashtable +
146-
inode_hash(ci->m_inode->i_sb, ci->m_inode->i_ino);
136+
inode_hash(d_inode(ci->m_de)->i_sb, (unsigned long)ci->m_de);
147137

148138
hlist_add_head(&ci->m_hash, b);
149139
}
@@ -157,7 +147,6 @@ static void ksmbd_inode_unhash(struct ksmbd_inode *ci)
157147

158148
static int ksmbd_inode_init(struct ksmbd_inode *ci, struct ksmbd_file *fp)
159149
{
160-
ci->m_inode = file_inode(fp->filp);
161150
atomic_set(&ci->m_count, 1);
162151
atomic_set(&ci->op_count, 0);
163152
atomic_set(&ci->sop_count, 0);
@@ -166,6 +155,7 @@ static int ksmbd_inode_init(struct ksmbd_inode *ci, struct ksmbd_file *fp)
166155
INIT_LIST_HEAD(&ci->m_fp_list);
167156
INIT_LIST_HEAD(&ci->m_op_list);
168157
rwlock_init(&ci->m_lock);
158+
ci->m_de = fp->filp->f_path.dentry;
169159
return 0;
170160
}
171161

@@ -488,12 +478,15 @@ struct ksmbd_file *ksmbd_lookup_fd_cguid(char *cguid)
488478
return fp;
489479
}
490480

491-
struct ksmbd_file *ksmbd_lookup_fd_inode(struct inode *inode)
481+
struct ksmbd_file *ksmbd_lookup_fd_inode(struct dentry *dentry)
492482
{
493483
struct ksmbd_file *lfp;
494484
struct ksmbd_inode *ci;
485+
struct inode *inode = d_inode(dentry);
495486

496-
ci = ksmbd_inode_lookup_by_vfsinode(inode);
487+
read_lock(&inode_hash_lock);
488+
ci = __ksmbd_inode_lookup(dentry);
489+
read_unlock(&inode_hash_lock);
497490
if (!ci)
498491
return NULL;
499492

fs/smb/server/vfs_cache.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ struct ksmbd_inode {
5151
atomic_t op_count;
5252
/* opinfo count for streams */
5353
atomic_t sop_count;
54-
struct inode *m_inode;
54+
struct dentry *m_de;
5555
unsigned int m_flags;
5656
struct hlist_node m_hash;
5757
struct list_head m_fp_list;
@@ -140,7 +140,7 @@ struct ksmbd_file *ksmbd_lookup_fd_slow(struct ksmbd_work *work, u64 id,
140140
void ksmbd_fd_put(struct ksmbd_work *work, struct ksmbd_file *fp);
141141
struct ksmbd_file *ksmbd_lookup_durable_fd(unsigned long long id);
142142
struct ksmbd_file *ksmbd_lookup_fd_cguid(char *cguid);
143-
struct ksmbd_file *ksmbd_lookup_fd_inode(struct inode *inode);
143+
struct ksmbd_file *ksmbd_lookup_fd_inode(struct dentry *dentry);
144144
unsigned int ksmbd_open_durable_fd(struct ksmbd_file *fp);
145145
struct ksmbd_file *ksmbd_open_fd(struct ksmbd_work *work, struct file *filp);
146146
void ksmbd_close_tree_conn_fds(struct ksmbd_work *work);
@@ -164,7 +164,7 @@ enum KSMBD_INODE_STATUS {
164164
KSMBD_INODE_STATUS_PENDING_DELETE,
165165
};
166166

167-
int ksmbd_query_inode_status(struct inode *inode);
167+
int ksmbd_query_inode_status(struct dentry *dentry);
168168
bool ksmbd_inode_pending_delete(struct ksmbd_file *fp);
169169
void ksmbd_set_inode_pending_delete(struct ksmbd_file *fp);
170170
void ksmbd_clear_inode_pending_delete(struct ksmbd_file *fp);

0 commit comments

Comments
 (0)