Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 2e54eb9

Browse files
petrvandrovecarndb
authored andcommitted
BKL: Remove BKL from ncpfs
Dozen of changes in ncpfs to provide some locking other than BKL. In readdir cache unlock and mark complete first page as last operation, so it can be used for synchronization, as code intended. When updating dentry name on case insensitive filesystems do at least some basic locking... Hold i_mutex when updating inode fields. Push some ncp_conn_is_valid down to ncp_request. Connection can become invalid at any moment, and fewer error code paths to test the better. Use i_size_{read,write} to modify file size. Set inode's backing_dev_info as ncpfs has its own special bdi. In ioctl unbreak ioctls invoked on filesystem mounted 'ro' - tests are for inode writeable or owner match, but were turned to filesystem writeable and inode writeable or owner match. Also collect all permission checks in single place. Add some locking, and remove comments saying that it would be cool to add some locks to the code. Constify some pointers. Signed-off-by: Petr Vandrovec <[email protected]> Signed-off-by: Arnd Bergmann <[email protected]>
1 parent 6005679 commit 2e54eb9

File tree

10 files changed

+487
-429
lines changed

10 files changed

+487
-429
lines changed

fs/ncpfs/dir.c

Lines changed: 129 additions & 92 deletions
Large diffs are not rendered by default.

fs/ncpfs/file.c

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,6 @@ ncp_file_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
113113
DPRINTK("ncp_file_read: enter %s/%s\n",
114114
dentry->d_parent->d_name.name, dentry->d_name.name);
115115

116-
if (!ncp_conn_valid(NCP_SERVER(inode)))
117-
return -EIO;
118-
119116
pos = *ppos;
120117

121118
if ((ssize_t) count < 0) {
@@ -192,13 +189,11 @@ ncp_file_write(struct file *file, const char __user *buf, size_t count, loff_t *
192189

193190
DPRINTK("ncp_file_write: enter %s/%s\n",
194191
dentry->d_parent->d_name.name, dentry->d_name.name);
195-
if (!ncp_conn_valid(NCP_SERVER(inode)))
196-
return -EIO;
197192
if ((ssize_t) count < 0)
198193
return -EINVAL;
199194
pos = *ppos;
200195
if (file->f_flags & O_APPEND) {
201-
pos = inode->i_size;
196+
pos = i_size_read(inode);
202197
}
203198

204199
if (pos + count > MAX_NON_LFS && !(file->f_flags&O_LARGEFILE)) {
@@ -264,8 +259,11 @@ ncp_file_write(struct file *file, const char __user *buf, size_t count, loff_t *
264259

265260
*ppos = pos;
266261

267-
if (pos > inode->i_size) {
268-
inode->i_size = pos;
262+
if (pos > i_size_read(inode)) {
263+
mutex_lock(&inode->i_mutex);
264+
if (pos > i_size_read(inode))
265+
i_size_write(inode, pos);
266+
mutex_unlock(&inode->i_mutex);
269267
}
270268
DPRINTK("ncp_file_write: exit %s/%s\n",
271269
dentry->d_parent->d_name.name, dentry->d_name.name);
@@ -281,18 +279,9 @@ static int ncp_release(struct inode *inode, struct file *file) {
281279
return 0;
282280
}
283281

284-
static loff_t ncp_remote_llseek(struct file *file, loff_t offset, int origin)
285-
{
286-
loff_t ret;
287-
lock_kernel();
288-
ret = generic_file_llseek_unlocked(file, offset, origin);
289-
unlock_kernel();
290-
return ret;
291-
}
292-
293282
const struct file_operations ncp_file_operations =
294283
{
295-
.llseek = ncp_remote_llseek,
284+
.llseek = generic_file_llseek,
296285
.read = ncp_file_read,
297286
.write = ncp_file_write,
298287
.unlocked_ioctl = ncp_ioctl,

fs/ncpfs/inode.c

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ static void ncp_update_dates(struct inode *inode, struct nw_info_struct *nwi)
139139
inode->i_mode = nwi->nfs.mode;
140140
}
141141

142-
inode->i_blocks = (inode->i_size + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT;
142+
inode->i_blocks = (i_size_read(inode) + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT;
143143

144144
inode->i_mtime.tv_sec = ncp_date_dos2unix(nwi->modifyTime, nwi->modifyDate);
145145
inode->i_ctime.tv_sec = ncp_date_dos2unix(nwi->creationTime, nwi->creationDate);
@@ -158,18 +158,21 @@ static void ncp_update_attrs(struct inode *inode, struct ncp_entry_info *nwinfo)
158158
inode->i_mode = server->m.dir_mode;
159159
/* for directories dataStreamSize seems to be some
160160
Object ID ??? */
161-
inode->i_size = NCP_BLOCK_SIZE;
161+
i_size_write(inode, NCP_BLOCK_SIZE);
162162
} else {
163+
u32 size;
164+
163165
inode->i_mode = server->m.file_mode;
164-
inode->i_size = le32_to_cpu(nwi->dataStreamSize);
166+
size = le32_to_cpu(nwi->dataStreamSize);
167+
i_size_write(inode, size);
165168
#ifdef CONFIG_NCPFS_EXTRAS
166169
if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS))
167170
&& (nwi->attributes & aSHARED)) {
168171
switch (nwi->attributes & (aHIDDEN|aSYSTEM)) {
169172
case aHIDDEN:
170173
if (server->m.flags & NCP_MOUNT_SYMLINKS) {
171-
if (/* (inode->i_size >= NCP_MIN_SYMLINK_SIZE)
172-
&& */ (inode->i_size <= NCP_MAX_SYMLINK_SIZE)) {
174+
if (/* (size >= NCP_MIN_SYMLINK_SIZE)
175+
&& */ (size <= NCP_MAX_SYMLINK_SIZE)) {
173176
inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK;
174177
NCP_FINFO(inode)->flags |= NCPI_KLUDGE_SYMLINK;
175178
break;
@@ -208,7 +211,7 @@ void ncp_update_inode2(struct inode* inode, struct ncp_entry_info *nwinfo)
208211
}
209212

210213
/*
211-
* Fill in the inode based on the ncp_entry_info structure.
214+
* Fill in the inode based on the ncp_entry_info structure. Used only for brand new inodes.
212215
*/
213216
static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo)
214217
{
@@ -254,6 +257,7 @@ ncp_iget(struct super_block *sb, struct ncp_entry_info *info)
254257
if (inode) {
255258
atomic_set(&NCP_FINFO(inode)->opened, info->opened);
256259

260+
inode->i_mapping->backing_dev_info = sb->s_bdi;
257261
inode->i_ino = info->ino;
258262
ncp_set_attr(inode, info);
259263
if (S_ISREG(inode->i_mode)) {
@@ -565,10 +569,12 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
565569
/* server->conn_status = 0; */
566570
/* server->root_dentry = NULL; */
567571
/* server->root_setuped = 0; */
572+
mutex_init(&server->root_setup_lock);
568573
#ifdef CONFIG_NCPFS_PACKET_SIGNING
569574
/* server->sign_wanted = 0; */
570575
/* server->sign_active = 0; */
571576
#endif
577+
init_rwsem(&server->auth_rwsem);
572578
server->auth.auth_type = NCP_AUTH_NONE;
573579
/* server->auth.object_name_len = 0; */
574580
/* server->auth.object_name = NULL; */
@@ -593,7 +599,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
593599
server->nls_io = load_nls_default();
594600
#endif /* CONFIG_NCPFS_NLS */
595601

596-
server->dentry_ttl = 0; /* no caching */
602+
atomic_set(&server->dentry_ttl, 0); /* no caching */
597603

598604
INIT_LIST_HEAD(&server->tx.requests);
599605
mutex_init(&server->rcv.creq_mutex);
@@ -658,8 +664,10 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
658664
goto out_disconnect;
659665
}
660666
}
667+
ncp_lock_server(server);
661668
if (options & 2)
662669
server->sign_wanted = 1;
670+
ncp_unlock_server(server);
663671
}
664672
else
665673
#endif /* CONFIG_NCPFS_PACKET_SIGNING */
@@ -720,6 +728,9 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
720728
unload_nls(server->nls_io);
721729
unload_nls(server->nls_vol);
722730
#endif
731+
mutex_destroy(&server->rcv.creq_mutex);
732+
mutex_destroy(&server->root_setup_lock);
733+
mutex_destroy(&server->mutex);
723734
out_fput2:
724735
if (server->info_filp)
725736
fput(server->info_filp);
@@ -743,8 +754,6 @@ static void ncp_put_super(struct super_block *sb)
743754
{
744755
struct ncp_server *server = NCP_SBP(sb);
745756

746-
lock_kernel();
747-
748757
ncp_lock_server(server);
749758
ncp_disconnect(server);
750759
ncp_unlock_server(server);
@@ -756,6 +765,9 @@ static void ncp_put_super(struct super_block *sb)
756765
unload_nls(server->nls_vol);
757766
unload_nls(server->nls_io);
758767
#endif /* CONFIG_NCPFS_NLS */
768+
mutex_destroy(&server->rcv.creq_mutex);
769+
mutex_destroy(&server->root_setup_lock);
770+
mutex_destroy(&server->mutex);
759771

760772
if (server->info_filp)
761773
fput(server->info_filp);
@@ -771,8 +783,6 @@ static void ncp_put_super(struct super_block *sb)
771783
vfree(server->packet);
772784
sb->s_fs_info = NULL;
773785
kfree(server);
774-
775-
unlock_kernel();
776786
}
777787

778788
static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
@@ -851,10 +861,8 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
851861

852862
result = -EIO;
853863

854-
lock_kernel();
855-
856864
server = NCP_SERVER(inode);
857-
if ((!server) || !ncp_conn_valid(server))
865+
if (!server) /* How this could happen? */
858866
goto out;
859867

860868
/* ageing the dentry to force validation */
@@ -981,8 +989,6 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
981989
result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
982990
inode, info_mask, &info);
983991
if (result != 0) {
984-
result = -EACCES;
985-
986992
if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) {
987993
/* NetWare seems not to allow this. I
988994
do not know why. So, just tell the
@@ -1005,7 +1011,8 @@ int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
10051011
mark_inode_dirty(inode);
10061012

10071013
out:
1008-
unlock_kernel();
1014+
if (result > 0)
1015+
result = -EACCES;
10091016
return result;
10101017
}
10111018

0 commit comments

Comments
 (0)