Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
a48489f8
Commit
a48489f8
authored
Feb 14, 2002
by
Alexander Viro
Committed by
Linus Torvalds
Feb 14, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] (3/5) more BKL shifting
BKL shifted into ->link(), check for S_ISDIR moved into vfs_link().
parent
90ed880a
Changes
19
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
86 additions
and
60 deletions
+86
-60
Documentation/filesystems/Locking
Documentation/filesystems/Locking
+1
-1
Documentation/filesystems/porting
Documentation/filesystems/porting
+10
-4
drivers/hotplug/pci_hotplug_core.c
drivers/hotplug/pci_hotplug_core.c
+2
-3
drivers/usb/inode.c
drivers/usb/inode.c
+2
-3
fs/affs/namei.c
fs/affs/namei.c
+5
-4
fs/bfs/dir.c
fs/bfs/dir.c
+5
-4
fs/coda/dir.c
fs/coda/dir.c
+5
-1
fs/ext2/namei.c
fs/ext2/namei.c
+5
-4
fs/ext3/namei.c
fs/ext3/namei.c
+8
-5
fs/jffs2/dir.c
fs/jffs2/dir.c
+5
-1
fs/minix/namei.c
fs/minix/namei.c
+5
-4
fs/namei.c
fs/namei.c
+2
-2
fs/nfs/dir.c
fs/nfs/dir.c
+2
-0
fs/ramfs/inode.c
fs/ramfs/inode.c
+2
-3
fs/reiserfs/namei.c
fs/reiserfs/namei.c
+4
-4
fs/sysv/namei.c
fs/sysv/namei.c
+5
-4
fs/udf/namei.c
fs/udf/namei.c
+8
-5
fs/ufs/namei.c
fs/ufs/namei.c
+8
-5
mm/shmem.c
mm/shmem.c
+2
-3
No files found.
Documentation/filesystems/Locking
View file @
a48489f8
...
...
@@ -55,7 +55,7 @@ locking rules:
BKL i_sem(inode)
lookup: no yes
create: no yes
link:
yes
yes
link:
no
yes
mknod: no yes
mkdir: no yes
unlink: no yes (both)
...
...
Documentation/filesystems/porting
View file @
a48489f8
...
...
@@ -80,9 +80,15 @@ can relax your locking.
---
[mandatory]
->lookup(), ->truncate(), ->create(), ->unlink(), ->mknod(), ->mkdir()
and
->rmdir() a
re called without BKL now. Grab it on the entry, drop upon
return - that will guarantee the same locking you used to have. If your
method or its parts do not need BKL - better yet, now you can shift
->lookup(), ->truncate(), ->create(), ->unlink(), ->mknod(), ->mkdir()
,
->rmdir() a
nd ->link() are called without BKL now. Grab it on the entry,
drop upon return - that will guarantee the same locking you used to have.
If your
method or its parts do not need BKL - better yet, now you can shift
lock_kernel() / unlock_kernel() so that they would protect exactly what
needs to be protected.
---
[informational]
check for ->link() target not being a directory is done by callers. Feel
free to drop it...
drivers/hotplug/pci_hotplug_core.c
View file @
a48489f8
...
...
@@ -159,10 +159,9 @@ static int pcihpfs_link (struct dentry *old_dentry, struct inode *dir,
{
struct
inode
*
inode
=
old_dentry
->
d_inode
;
if
(
S_ISDIR
(
inode
->
i_mode
))
return
-
EPERM
;
lock_kernel
();
inode
->
i_nlink
++
;
unlock_kernel
();
atomic_inc
(
&
inode
->
i_count
);
dget
(
dentry
);
d_instantiate
(
dentry
,
inode
);
...
...
drivers/usb/inode.c
View file @
a48489f8
...
...
@@ -216,10 +216,9 @@ static int usbfs_link (struct dentry *old_dentry, struct inode *dir,
{
struct
inode
*
inode
=
old_dentry
->
d_inode
;
if
(
S_ISDIR
(
inode
->
i_mode
))
return
-
EPERM
;
lock_kernel
();
inode
->
i_nlink
++
;
unlock_kernel
();
atomic_inc
(
&
inode
->
i_count
);
dget
(
dentry
);
d_instantiate
(
dentry
,
inode
);
...
...
fs/affs/namei.c
View file @
a48489f8
...
...
@@ -435,16 +435,17 @@ affs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
pr_debug
(
"AFFS: link(%u, %u,
\"
%.*s
\"
)
\n
"
,
(
u32
)
inode
->
i_ino
,
(
u32
)
dir
->
i_ino
,
(
int
)
dentry
->
d_name
.
len
,
dentry
->
d_name
.
name
);
if
(
S_ISDIR
(
inode
->
i_mode
))
return
-
EPERM
;
error
=
affs_add_entry
(
dir
,
inode
,
dentry
,
S_ISDIR
(
inode
->
i_mode
)
?
ST_LINKDIR
:
ST_LINKFILE
);
lock_kernel
();
error
=
affs_add_entry
(
dir
,
inode
,
dentry
,
ST_LINKFILE
);
if
(
error
)
{
/* WTF??? */
inode
->
i_nlink
=
0
;
mark_inode_dirty
(
inode
);
iput
(
inode
);
unlock_kernel
();
return
error
;
}
unlock_kernel
();
return
0
;
}
...
...
fs/bfs/dir.c
View file @
a48489f8
...
...
@@ -151,17 +151,18 @@ static int bfs_link(struct dentry * old, struct inode * dir, struct dentry * new
struct
inode
*
inode
=
old
->
d_inode
;
int
err
;
if
(
S_ISDIR
(
inode
->
i_mode
))
return
-
EPERM
;
lock_kernel
();
err
=
bfs_add_entry
(
dir
,
new
->
d_name
.
name
,
new
->
d_name
.
len
,
inode
->
i_ino
);
if
(
err
)
if
(
err
)
{
unlock_kernel
();
return
err
;
}
inode
->
i_nlink
++
;
inode
->
i_ctime
=
CURRENT_TIME
;
mark_inode_dirty
(
inode
);
atomic_inc
(
&
inode
->
i_count
);
d_instantiate
(
new
,
inode
);
unlock_kernel
();
return
0
;
}
...
...
fs/coda/dir.c
View file @
a48489f8
...
...
@@ -362,10 +362,13 @@ static int coda_link(struct dentry *source_de, struct inode *dir_inode,
int
len
=
de
->
d_name
.
len
;
int
error
;
lock_kernel
();
coda_vfs_stat
.
link
++
;
if
(
coda_isroot
(
dir_inode
)
&&
coda_iscontrol
(
name
,
len
))
if
(
coda_isroot
(
dir_inode
)
&&
coda_iscontrol
(
name
,
len
))
{
unlock_kernel
();
return
-
EPERM
;
}
CDEBUG
(
D_INODE
,
"old: fid: %s
\n
"
,
coda_i2s
(
inode
));
CDEBUG
(
D_INODE
,
"directory: %s
\n
"
,
coda_i2s
(
dir_inode
));
...
...
@@ -385,6 +388,7 @@ static int coda_link(struct dentry *source_de, struct inode *dir_inode,
out:
CDEBUG
(
D_INODE
,
"link result %d
\n
"
,
error
);
unlock_kernel
();
return
(
error
);
}
...
...
fs/ext2/namei.c
View file @
a48489f8
...
...
@@ -168,14 +168,15 @@ static int ext2_link (struct dentry * old_dentry, struct inode * dir,
{
struct
inode
*
inode
=
old_dentry
->
d_inode
;
if
(
S_ISDIR
(
inode
->
i_mode
))
return
-
EPERM
;
if
(
inode
->
i_nlink
>=
EXT2_LINK_MAX
)
lock_kernel
();
if
(
inode
->
i_nlink
>=
EXT2_LINK_MAX
)
{
unlock_kernel
();
return
-
EMLINK
;
}
inode
->
i_ctime
=
CURRENT_TIME
;
ext2_inc_count
(
inode
);
unlock_kernel
();
atomic_inc
(
&
inode
->
i_count
);
return
ext2_add_nondir
(
dentry
,
inode
);
...
...
fs/ext3/namei.c
View file @
a48489f8
...
...
@@ -978,15 +978,17 @@ static int ext3_link (struct dentry * old_dentry,
struct
inode
*
inode
=
old_dentry
->
d_inode
;
int
err
;
if
(
S_ISDIR
(
inode
->
i_mode
))
return
-
EPERM
;
if
(
inode
->
i_nlink
>=
EXT3_LINK_MAX
)
lock_kernel
();
if
(
inode
->
i_nlink
>=
EXT3_LINK_MAX
)
{
unlock_kernel
();
return
-
EMLINK
;
}
handle
=
ext3_journal_start
(
dir
,
EXT3_DATA_TRANS_BLOCKS
);
if
(
IS_ERR
(
handle
))
if
(
IS_ERR
(
handle
))
{
unlock_kernel
();
return
PTR_ERR
(
handle
);
}
if
(
IS_SYNC
(
dir
))
handle
->
h_sync
=
1
;
...
...
@@ -998,6 +1000,7 @@ static int ext3_link (struct dentry * old_dentry,
ext3_mark_inode_dirty
(
handle
,
inode
);
err
=
ext3_add_nondir
(
handle
,
dentry
,
inode
);
ext3_journal_stop
(
handle
,
dir
);
unlock_kernel
();
return
err
;
}
...
...
fs/jffs2/dir.c
View file @
a48489f8
...
...
@@ -501,11 +501,15 @@ static int jffs2_do_link (struct dentry *old_dentry, struct inode *dir_i, struct
static
int
jffs2_link
(
struct
dentry
*
old_dentry
,
struct
inode
*
dir_i
,
struct
dentry
*
dentry
)
{
int
ret
=
jffs2_do_link
(
old_dentry
,
dir_i
,
dentry
,
0
);
int
ret
;
lock_kernel
();
ret
=
jffs2_do_link
(
old_dentry
,
dir_i
,
dentry
,
0
);
if
(
!
ret
)
{
d_instantiate
(
dentry
,
old_dentry
->
d_inode
);
atomic_inc
(
&
old_dentry
->
d_inode
->
i_count
);
}
unlock_kernel
();
return
ret
;
}
...
...
fs/minix/namei.c
View file @
a48489f8
...
...
@@ -136,14 +136,15 @@ static int minix_link(struct dentry * old_dentry, struct inode * dir,
{
struct
inode
*
inode
=
old_dentry
->
d_inode
;
if
(
S_ISDIR
(
inode
->
i_mode
))
return
-
EPERM
;
if
(
inode
->
i_nlink
>=
inode
->
i_sb
->
u
.
minix_sb
.
s_link_max
)
lock_kernel
();
if
(
inode
->
i_nlink
>=
inode
->
i_sb
->
u
.
minix_sb
.
s_link_max
)
{
unlock_kernel
();
return
-
EMLINK
;
}
inode
->
i_ctime
=
CURRENT_TIME
;
inc_count
(
inode
);
unlock_kernel
();
atomic_inc
(
&
inode
->
i_count
);
return
add_nondir
(
dentry
,
inode
);
}
...
...
fs/namei.c
View file @
a48489f8
...
...
@@ -1613,11 +1613,11 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
return
-
EPERM
;
if
(
!
dir
->
i_op
||
!
dir
->
i_op
->
link
)
return
-
EPERM
;
if
(
S_ISDIR
(
old_dentry
->
d_inode
->
i_mode
))
return
-
EPERM
;
DQUOT_INIT
(
dir
);
lock_kernel
();
error
=
dir
->
i_op
->
link
(
old_dentry
,
dir
,
new_dentry
);
unlock_kernel
();
if
(
!
error
)
inode_dir_notify
(
dir
,
DN_CREATE
);
return
error
;
...
...
fs/nfs/dir.c
View file @
a48489f8
...
...
@@ -951,10 +951,12 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
* Since nfs_proc_link doesn't return a file handle,
* we can't use the existing dentry.
*/
lock_kernel
();
d_drop
(
dentry
);
nfs_zap_caches
(
dir
);
NFS_CACHEINV
(
inode
);
error
=
NFS_PROTO
(
dir
)
->
link
(
inode
,
dir
,
&
dentry
->
d_name
);
unlock_kernel
();
return
error
;
}
...
...
fs/ramfs/inode.c
View file @
a48489f8
...
...
@@ -166,10 +166,9 @@ static int ramfs_link(struct dentry *old_dentry, struct inode * dir, struct dent
{
struct
inode
*
inode
=
old_dentry
->
d_inode
;
if
(
S_ISDIR
(
inode
->
i_mode
))
return
-
EPERM
;
lock_kernel
();
inode
->
i_nlink
++
;
unlock_kernel
();
atomic_inc
(
&
inode
->
i_count
);
/* New dentry reference */
dget
(
dentry
);
/* Extra pinning count for the created dentry */
d_instantiate
(
dentry
,
inode
);
...
...
fs/reiserfs/namei.c
View file @
a48489f8
...
...
@@ -978,12 +978,10 @@ static int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct
struct
reiserfs_transaction_handle
th
;
int
jbegin_count
=
JOURNAL_PER_BALANCE_CNT
*
3
;
if
(
S_ISDIR
(
inode
->
i_mode
))
return
-
EPERM
;
lock_kernel
();
if
(
inode
->
i_nlink
>=
REISERFS_LINK_MAX
)
{
//FIXME: sd_nlink is 32 bit for new files
unlock_kernel
();
return
-
EMLINK
;
}
...
...
@@ -1000,6 +998,7 @@ static int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct
if
(
retval
)
{
pop_journal_writer
(
windex
)
;
journal_end
(
&
th
,
dir
->
i_sb
,
jbegin_count
)
;
unlock_kernel
();
return
retval
;
}
...
...
@@ -1011,6 +1010,7 @@ static int reiserfs_link (struct dentry * old_dentry, struct inode * dir, struct
d_instantiate
(
dentry
,
inode
);
pop_journal_writer
(
windex
)
;
journal_end
(
&
th
,
dir
->
i_sb
,
jbegin_count
)
;
unlock_kernel
();
return
0
;
}
...
...
fs/sysv/namei.c
View file @
a48489f8
...
...
@@ -142,14 +142,15 @@ static int sysv_link(struct dentry * old_dentry, struct inode * dir,
{
struct
inode
*
inode
=
old_dentry
->
d_inode
;
if
(
S_ISDIR
(
inode
->
i_mode
))
return
-
EPERM
;
if
(
inode
->
i_nlink
>=
inode
->
i_sb
->
sv_link_max
)
lock_kernel
();
if
(
inode
->
i_nlink
>=
inode
->
i_sb
->
sv_link_max
)
{
unlock_kernel
();
return
-
EMLINK
;
}
inode
->
i_ctime
=
CURRENT_TIME
;
inc_count
(
inode
);
unlock_kernel
();
atomic_inc
(
&
inode
->
i_count
);
return
add_nondir
(
dentry
,
inode
);
...
...
fs/udf/namei.c
View file @
a48489f8
...
...
@@ -1109,14 +1109,16 @@ static int udf_link(struct dentry * old_dentry, struct inode * dir,
int
err
;
struct
FileIdentDesc
cfi
,
*
fi
;
if
(
S_ISDIR
(
inode
->
i_mode
))
return
-
EPERM
;
if
(
inode
->
i_nlink
>=
(
256
<<
sizeof
(
inode
->
i_nlink
))
-
1
)
lock_kernel
();
if
(
inode
->
i_nlink
>=
(
256
<<
sizeof
(
inode
->
i_nlink
))
-
1
)
{
unlock_kernel
();
return
-
EMLINK
;
}
if
(
!
(
fi
=
udf_add_entry
(
dir
,
dentry
,
&
fibh
,
&
cfi
,
&
err
)))
if
(
!
(
fi
=
udf_add_entry
(
dir
,
dentry
,
&
fibh
,
&
cfi
,
&
err
)))
{
unlock_kernel
();
return
err
;
}
cfi
.
icb
.
extLength
=
cpu_to_le32
(
inode
->
i_sb
->
s_blocksize
);
cfi
.
icb
.
extLocation
=
cpu_to_lelb
(
UDF_I_LOCATION
(
inode
));
if
(
UDF_SB_LVIDBH
(
inode
->
i_sb
))
...
...
@@ -1146,6 +1148,7 @@ static int udf_link(struct dentry * old_dentry, struct inode * dir,
mark_inode_dirty
(
inode
);
atomic_inc
(
&
inode
->
i_count
);
d_instantiate
(
dentry
,
inode
);
unlock_kernel
();
return
0
;
}
...
...
fs/ufs/namei.c
View file @
a48489f8
...
...
@@ -166,18 +166,21 @@ static int ufs_link (struct dentry * old_dentry, struct inode * dir,
struct
dentry
*
dentry
)
{
struct
inode
*
inode
=
old_dentry
->
d_inode
;
int
error
;
if
(
S_ISDIR
(
inode
->
i_mode
))
return
-
EPERM
;
if
(
inode
->
i_nlink
>=
UFS_LINK_MAX
)
lock_kernel
();
if
(
inode
->
i_nlink
>=
UFS_LINK_MAX
)
{
unlock_kernel
();
return
-
EMLINK
;
}
inode
->
i_ctime
=
CURRENT_TIME
;
ufs_inc_count
(
inode
);
atomic_inc
(
&
inode
->
i_count
);
return
ufs_add_nondir
(
dentry
,
inode
);
error
=
ufs_add_nondir
(
dentry
,
inode
);
unlock_kernel
();
return
error
;
}
static
int
ufs_mkdir
(
struct
inode
*
dir
,
struct
dentry
*
dentry
,
int
mode
)
...
...
mm/shmem.c
View file @
a48489f8
...
...
@@ -1021,11 +1021,10 @@ static int shmem_link(struct dentry *old_dentry, struct inode * dir, struct dent
{
struct
inode
*
inode
=
old_dentry
->
d_inode
;
if
(
S_ISDIR
(
inode
->
i_mode
))
return
-
EPERM
;
inode
->
i_ctime
=
dir
->
i_ctime
=
dir
->
i_mtime
=
CURRENT_TIME
;
lock_kernel
();
inode
->
i_nlink
++
;
unlock_kernel
();
atomic_inc
(
&
inode
->
i_count
);
/* New dentry reference */
dget
(
dentry
);
/* Extra pinning count for the created dentry */
d_instantiate
(
dentry
,
inode
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment