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
Kirill Smelkov
linux
Commits
84f922f1
Commit
84f922f1
authored
Apr 29, 2002
by
Christoph Hellwig
Browse files
Options
Browse Files
Download
Plain Diff
Merge 2.5.11 into sysvfs development tree
parents
e66d5915
825ab03e
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
605 additions
and
550 deletions
+605
-550
fs/sysv/balloc.c
fs/sysv/balloc.c
+39
-37
fs/sysv/dir.c
fs/sysv/dir.c
+10
-9
fs/sysv/file.c
fs/sysv/file.c
+1
-2
fs/sysv/ialloc.c
fs/sysv/ialloc.c
+38
-32
fs/sysv/inode.c
fs/sysv/inode.c
+65
-51
fs/sysv/itree.c
fs/sysv/itree.c
+31
-23
fs/sysv/namei.c
fs/sysv/namei.c
+4
-5
fs/sysv/super.c
fs/sysv/super.c
+171
-150
fs/sysv/symlink.c
fs/sysv/symlink.c
+1
-2
fs/sysv/sysv.h
fs/sysv/sysv.h
+236
-0
include/linux/fs.h
include/linux/fs.h
+0
-2
include/linux/sysv_fs.h
include/linux/sysv_fs.h
+9
-219
include/linux/sysv_fs_i.h
include/linux/sysv_fs_i.h
+0
-18
No files found.
fs/sysv/balloc.c
View file @
84f922f1
...
...
@@ -19,9 +19,8 @@
* This file contains code for allocating/freeing blocks.
*/
#include <linux/fs.h>
#include <linux/sysv_fs.h>
#include <linux/locks.h>
#include "sysv.h"
/* We don't trust the value of
sb->sv_sbd2->s_tfree = *sb->sv_free_blocks
...
...
@@ -31,7 +30,7 @@ static inline u32 *get_chunk(struct super_block *sb, struct buffer_head *bh)
{
char
*
bh_data
=
bh
->
b_data
;
if
(
sb
->
sv
_type
==
FSTYPE_SYSV4
)
if
(
SYSV_SB
(
sb
)
->
s
_type
==
FSTYPE_SYSV4
)
return
(
u32
*
)(
bh_data
+
4
);
else
return
(
u32
*
)(
bh_data
+
2
);
...
...
@@ -41,28 +40,29 @@ static inline u32 *get_chunk(struct super_block *sb, struct buffer_head *bh)
void
sysv_free_block
(
struct
super_block
*
sb
,
u32
nr
)
{
struct
sysv_sb_info
*
sbi
=
SYSV_SB
(
sb
);
struct
buffer_head
*
bh
;
u32
*
blocks
=
sb
->
sv
_bcache
;
u32
*
blocks
=
sb
i
->
s
_bcache
;
unsigned
count
;
unsigned
block
=
fs32_to_cpu
(
sb
,
nr
);
unsigned
block
=
fs32_to_cpu
(
sb
i
,
nr
);
/*
* This code does not work at all for AFS (it has a bitmap
* free list). As AFS is supposed to be read-only no one
* should call this for an AFS filesystem anyway...
*/
if
(
sb
->
sv
_type
==
FSTYPE_AFS
)
if
(
sb
i
->
s
_type
==
FSTYPE_AFS
)
return
;
if
(
block
<
sb
->
sv_firstdatazone
||
block
>=
sb
->
sv
_nzones
)
{
if
(
block
<
sb
i
->
s_firstdatazone
||
block
>=
sbi
->
s
_nzones
)
{
printk
(
"sysv_free_block: trying to free block not in datazone
\n
"
);
return
;
}
lock_super
(
sb
);
count
=
fs16_to_cpu
(
sb
,
*
sb
->
sv
_bcache_count
);
count
=
fs16_to_cpu
(
sb
i
,
*
sbi
->
s
_bcache_count
);
if
(
count
>
sb
->
sv
_flc_size
)
{
if
(
count
>
sb
i
->
s
_flc_size
)
{
printk
(
"sysv_free_block: flc_count > flc_size
\n
"
);
unlock_super
(
sb
);
return
;
...
...
@@ -71,8 +71,8 @@ void sysv_free_block(struct super_block * sb, u32 nr)
* into this block being freed, ditto if it's completely empty
* (applies only on Coherent).
*/
if
(
count
==
sb
->
sv
_flc_size
||
count
==
0
)
{
block
+=
sb
->
sv
_block_base
;
if
(
count
==
sb
i
->
s
_flc_size
||
count
==
0
)
{
block
+=
sb
i
->
s
_block_base
;
bh
=
sb_getblk
(
sb
,
block
);
if
(
!
bh
)
{
printk
(
"sysv_free_block: getblk() failed
\n
"
);
...
...
@@ -80,42 +80,43 @@ void sysv_free_block(struct super_block * sb, u32 nr)
return
;
}
memset
(
bh
->
b_data
,
0
,
sb
->
s_blocksize
);
*
(
u16
*
)
bh
->
b_data
=
cpu_to_fs16
(
sb
,
count
);
*
(
u16
*
)
bh
->
b_data
=
cpu_to_fs16
(
sb
i
,
count
);
memcpy
(
get_chunk
(
sb
,
bh
),
blocks
,
count
*
sizeof
(
sysv_zone_t
));
mark_buffer_dirty
(
bh
);
mark_buffer_uptodate
(
bh
,
1
);
brelse
(
bh
);
count
=
0
;
}
sb
->
sv
_bcache
[
count
++
]
=
nr
;
sb
i
->
s
_bcache
[
count
++
]
=
nr
;
*
sb
->
sv_bcache_count
=
cpu_to_fs16
(
sb
,
count
);
fs32_add
(
sb
,
sb
->
sv
_free_blocks
,
1
);
*
sb
i
->
s_bcache_count
=
cpu_to_fs16
(
sbi
,
count
);
fs32_add
(
sb
i
,
sbi
->
s
_free_blocks
,
1
);
dirty_sb
(
sb
);
unlock_super
(
sb
);
}
u32
sysv_new_block
(
struct
super_block
*
sb
)
{
struct
sysv_sb_info
*
sbi
=
SYSV_SB
(
sb
);
unsigned
int
block
;
u32
nr
;
struct
buffer_head
*
bh
;
unsigned
count
;
lock_super
(
sb
);
count
=
fs16_to_cpu
(
sb
,
*
sb
->
sv
_bcache_count
);
count
=
fs16_to_cpu
(
sb
i
,
*
sbi
->
s
_bcache_count
);
if
(
count
==
0
)
/* Applies only to Coherent FS */
goto
Enospc
;
nr
=
sb
->
sv
_bcache
[
--
count
];
nr
=
sb
i
->
s
_bcache
[
--
count
];
if
(
nr
==
0
)
/* Applies only to Xenix FS, SystemV FS */
goto
Enospc
;
block
=
fs32_to_cpu
(
sb
,
nr
);
block
=
fs32_to_cpu
(
sb
i
,
nr
);
*
sb
->
sv_bcache_count
=
cpu_to_fs16
(
sb
,
count
);
*
sb
i
->
s_bcache_count
=
cpu_to_fs16
(
sbi
,
count
);
if
(
block
<
sb
->
sv_firstdatazone
||
block
>=
sb
->
sv
_nzones
)
{
if
(
block
<
sb
i
->
s_firstdatazone
||
block
>=
sbi
->
s
_nzones
)
{
printk
(
"sysv_new_block: new block %d is not in data zone
\n
"
,
block
);
goto
Enospc
;
...
...
@@ -124,26 +125,26 @@ u32 sysv_new_block(struct super_block * sb)
if
(
count
==
0
)
{
/* the last block continues the free list */
unsigned
count
;
block
+=
sb
->
sv
_block_base
;
block
+=
sb
i
->
s
_block_base
;
if
(
!
(
bh
=
sb_bread
(
sb
,
block
)))
{
printk
(
"sysv_new_block: cannot read free-list block
\n
"
);
/* retry this same block next time */
*
sb
->
sv_bcache_count
=
cpu_to_fs16
(
sb
,
1
);
*
sb
i
->
s_bcache_count
=
cpu_to_fs16
(
sbi
,
1
);
goto
Enospc
;
}
count
=
fs16_to_cpu
(
sb
,
*
(
u16
*
)
bh
->
b_data
);
if
(
count
>
sb
->
sv
_flc_size
)
{
count
=
fs16_to_cpu
(
sb
i
,
*
(
u16
*
)
bh
->
b_data
);
if
(
count
>
sb
i
->
s
_flc_size
)
{
printk
(
"sysv_new_block: free-list block with >flc_size entries
\n
"
);
brelse
(
bh
);
goto
Enospc
;
}
*
sb
->
sv_bcache_count
=
cpu_to_fs16
(
sb
,
count
);
memcpy
(
sb
->
sv
_bcache
,
get_chunk
(
sb
,
bh
),
*
sb
i
->
s_bcache_count
=
cpu_to_fs16
(
sbi
,
count
);
memcpy
(
sb
i
->
s
_bcache
,
get_chunk
(
sb
,
bh
),
count
*
sizeof
(
sysv_zone_t
));
brelse
(
bh
);
}
/* Now the free list head in the superblock is valid again. */
fs32_add
(
sb
,
sb
->
sv
_free_blocks
,
-
1
);
fs32_add
(
sb
i
,
sbi
->
s
_free_blocks
,
-
1
);
dirty_sb
(
sb
);
unlock_super
(
sb
);
return
nr
;
...
...
@@ -155,6 +156,7 @@ u32 sysv_new_block(struct super_block * sb)
unsigned
long
sysv_count_free_blocks
(
struct
super_block
*
sb
)
{
struct
sysv_sb_info
*
sbi
=
SYSV_SB
(
sb
);
int
sb_count
;
int
count
;
struct
buffer_head
*
bh
=
NULL
;
...
...
@@ -167,21 +169,21 @@ unsigned long sysv_count_free_blocks(struct super_block * sb)
* free list). As AFS is supposed to be read-only we just
* lie and say it has no free block at all.
*/
if
(
sb
->
sv
_type
==
FSTYPE_AFS
)
if
(
sb
i
->
s
_type
==
FSTYPE_AFS
)
return
0
;
lock_super
(
sb
);
sb_count
=
fs32_to_cpu
(
sb
,
*
sb
->
sv
_free_blocks
);
sb_count
=
fs32_to_cpu
(
sb
i
,
*
sbi
->
s
_free_blocks
);
if
(
0
)
goto
trust_sb
;
/* this causes a lot of disk traffic ... */
count
=
0
;
n
=
fs16_to_cpu
(
sb
,
*
sb
->
sv
_bcache_count
);
blocks
=
sb
->
sv
_bcache
;
n
=
fs16_to_cpu
(
sb
i
,
*
sbi
->
s
_bcache_count
);
blocks
=
sb
i
->
s
_bcache
;
while
(
1
)
{
if
(
n
>
sb
->
sv
_flc_size
)
if
(
n
>
sb
i
->
s
_flc_size
)
goto
E2big
;
block
=
0
;
while
(
n
&&
(
block
=
blocks
[
--
n
])
!=
0
)
...
...
@@ -189,17 +191,17 @@ unsigned long sysv_count_free_blocks(struct super_block * sb)
if
(
block
==
0
)
break
;
block
=
fs32_to_cpu
(
sb
,
block
);
block
=
fs32_to_cpu
(
sb
i
,
block
);
if
(
bh
)
brelse
(
bh
);
if
(
block
<
sb
->
sv_firstdatazone
||
block
>=
sb
->
sv
_nzones
)
if
(
block
<
sb
i
->
s_firstdatazone
||
block
>=
sbi
->
s
_nzones
)
goto
Einval
;
block
+=
sb
->
sv
_block_base
;
block
+=
sb
i
->
s
_block_base
;
bh
=
sb_bread
(
sb
,
block
);
if
(
!
bh
)
goto
Eio
;
n
=
fs16_to_cpu
(
sb
,
*
(
u16
*
)
bh
->
b_data
);
n
=
fs16_to_cpu
(
sb
i
,
*
(
u16
*
)
bh
->
b_data
);
blocks
=
get_chunk
(
sb
,
bh
);
}
if
(
bh
)
...
...
@@ -228,7 +230,7 @@ unsigned long sysv_count_free_blocks(struct super_block * sb)
printk
(
"sysv_count_free_blocks: free block count was %d, "
"correcting to %d
\n
"
,
sb_count
,
count
);
if
(
!
(
sb
->
s_flags
&
MS_RDONLY
))
{
*
sb
->
sv_free_blocks
=
cpu_to_fs32
(
sb
,
count
);
*
sb
i
->
s_free_blocks
=
cpu_to_fs32
(
sbi
,
count
);
dirty_sb
(
sb
);
}
goto
done
;
...
...
fs/sysv/dir.c
View file @
84f922f1
...
...
@@ -13,9 +13,8 @@
* SystemV/Coherent directory handling functions
*/
#include <linux/fs.h>
#include <linux/sysv_fs.h>
#include <linux/pagemap.h>
#include "sysv.h"
static
int
sysv_readdir
(
struct
file
*
,
void
*
,
filldir_t
);
...
...
@@ -104,7 +103,8 @@ static int sysv_readdir(struct file * filp, void * dirent, filldir_t filldir)
over
=
filldir
(
dirent
,
name
,
strnlen
(
name
,
SYSV_NAMELEN
),
(
n
<<
PAGE_CACHE_SHIFT
)
|
offset
,
fs16_to_cpu
(
sb
,
de
->
inode
),
DT_UNKNOWN
);
fs16_to_cpu
(
SYSV_SB
(
sb
),
de
->
inode
),
DT_UNKNOWN
);
if
(
over
)
{
dir_put_page
(
page
);
goto
done
;
...
...
@@ -228,7 +228,7 @@ int sysv_add_link(struct dentry *dentry, struct inode *inode)
goto
out_unlock
;
memcpy
(
de
->
name
,
name
,
namelen
);
memset
(
de
->
name
+
namelen
,
0
,
SYSV_DIRSIZE
-
namelen
-
2
);
de
->
inode
=
cpu_to_fs16
(
inode
->
i_sb
,
inode
->
i_ino
);
de
->
inode
=
cpu_to_fs16
(
SYSV_SB
(
inode
->
i_sb
)
,
inode
->
i_ino
);
err
=
dir_commit_chunk
(
page
,
from
,
to
);
dir
->
i_mtime
=
dir
->
i_ctime
=
CURRENT_TIME
;
mark_inode_dirty
(
dir
);
...
...
@@ -280,10 +280,10 @@ int sysv_make_empty(struct inode *inode, struct inode *dir)
memset
(
base
,
0
,
PAGE_CACHE_SIZE
);
de
=
(
struct
sysv_dir_entry
*
)
base
;
de
->
inode
=
cpu_to_fs16
(
inode
->
i_sb
,
inode
->
i_ino
);
de
->
inode
=
cpu_to_fs16
(
SYSV_SB
(
inode
->
i_sb
)
,
inode
->
i_ino
);
strcpy
(
de
->
name
,
"."
);
de
++
;
de
->
inode
=
cpu_to_fs16
(
inode
->
i_sb
,
dir
->
i_ino
);
de
->
inode
=
cpu_to_fs16
(
SYSV_SB
(
inode
->
i_sb
)
,
dir
->
i_ino
);
strcpy
(
de
->
name
,
".."
);
err
=
dir_commit_chunk
(
page
,
0
,
2
*
SYSV_DIRSIZE
);
...
...
@@ -321,7 +321,8 @@ int sysv_empty_dir(struct inode * inode)
if
(
de
->
name
[
0
]
!=
'.'
)
goto
not_empty
;
if
(
!
de
->
name
[
1
])
{
if
(
de
->
inode
==
cpu_to_fs16
(
sb
,
inode
->
i_ino
))
if
(
de
->
inode
==
cpu_to_fs16
(
SYSV_SB
(
sb
),
inode
->
i_ino
))
continue
;
goto
not_empty
;
}
...
...
@@ -350,7 +351,7 @@ void sysv_set_link(struct sysv_dir_entry *de, struct page *page,
err
=
page
->
mapping
->
a_ops
->
prepare_write
(
NULL
,
page
,
from
,
to
);
if
(
err
)
BUG
();
de
->
inode
=
cpu_to_fs16
(
inode
->
i_sb
,
inode
->
i_ino
);
de
->
inode
=
cpu_to_fs16
(
SYSV_SB
(
inode
->
i_sb
)
,
inode
->
i_ino
);
err
=
dir_commit_chunk
(
page
,
from
,
to
);
UnlockPage
(
page
);
dir_put_page
(
page
);
...
...
@@ -377,7 +378,7 @@ ino_t sysv_inode_by_name(struct dentry *dentry)
ino_t
res
=
0
;
if
(
de
)
{
res
=
fs16_to_cpu
(
dentry
->
d_sb
,
de
->
inode
);
res
=
fs16_to_cpu
(
SYSV_SB
(
dentry
->
d_sb
)
,
de
->
inode
);
dir_put_page
(
page
);
}
return
res
;
...
...
fs/sysv/file.c
View file @
84f922f1
...
...
@@ -13,8 +13,7 @@
* SystemV/Coherent regular file handling primitives
*/
#include <linux/fs.h>
#include <linux/sysv_fs.h>
#include "sysv.h"
/*
* We have mostly NULLs here: the current defaults are OK for
...
...
fs/sysv/ialloc.c
View file @
84f922f1
...
...
@@ -20,12 +20,11 @@
*/
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/sysv_fs.h>
#include <linux/stddef.h>
#include <linux/stat.h>
#include <linux/string.h>
#include <linux/locks.h>
#include "sysv.h"
/* We don't trust the value of
sb->sv_sbd2->s_tinode = *sb->sv_sb_total_free_inodes
...
...
@@ -37,33 +36,38 @@
static
inline
sysv_ino_t
*
sv_sb_fic_inode
(
struct
super_block
*
sb
,
unsigned
int
i
)
{
if
(
sb
->
sv_bh1
==
sb
->
sv_bh2
)
return
&
sb
->
sv_sb_fic_inodes
[
i
];
struct
sysv_sb_info
*
sbi
=
SYSV_SB
(
sb
);
if
(
sbi
->
s_bh1
==
sbi
->
s_bh2
)
return
&
sbi
->
s_sb_fic_inodes
[
i
];
else
{
/* 512 byte Xenix FS */
unsigned
int
offset
=
offsetof
(
struct
xenix_super_block
,
s_inode
[
i
]);
if
(
offset
<
512
)
return
(
sysv_ino_t
*
)(
sb
->
sv
_sbd1
+
offset
);
return
(
sysv_ino_t
*
)(
sb
i
->
s
_sbd1
+
offset
);
else
return
(
sysv_ino_t
*
)(
sb
->
sv
_sbd2
+
offset
);
return
(
sysv_ino_t
*
)(
sb
i
->
s
_sbd2
+
offset
);
}
}
struct
sysv_inode
*
sysv_raw_inode
(
struct
super_block
*
sb
,
unsigned
ino
,
struct
buffer_head
**
bh
)
{
struct
sysv_sb_info
*
sbi
=
SYSV_SB
(
sb
);
struct
sysv_inode
*
res
;
int
block
=
sb
->
sv_firstinodezone
+
sb
->
sv_block_base
;
block
+=
(
ino
-
1
)
>>
sb
->
sv_inodes_per_block_bits
;
int
block
=
sbi
->
s_firstinodezone
+
sbi
->
s_block_base
;
block
+=
(
ino
-
1
)
>>
sbi
->
s_inodes_per_block_bits
;
*
bh
=
sb_bread
(
sb
,
block
);
if
(
!*
bh
)
return
NULL
;
res
=
(
struct
sysv_inode
*
)
(
*
bh
)
->
b_data
;
return
res
+
((
ino
-
1
)
&
sb
->
sv
_inodes_per_block_1
);
res
=
(
struct
sysv_inode
*
)(
*
bh
)
->
b_data
;
return
res
+
((
ino
-
1
)
&
sb
i
->
s
_inodes_per_block_1
);
}
static
int
refill_free_cache
(
struct
super_block
*
sb
)
{
struct
sysv_sb_info
*
sbi
=
SYSV_SB
(
sb
);
struct
buffer_head
*
bh
;
struct
sysv_inode
*
raw_inode
;
int
i
=
0
,
ino
;
...
...
@@ -72,13 +76,13 @@ static int refill_free_cache(struct super_block *sb)
raw_inode
=
sysv_raw_inode
(
sb
,
ino
,
&
bh
);
if
(
!
raw_inode
)
goto
out
;
while
(
ino
<=
sb
->
sv
_ninodes
)
{
while
(
ino
<=
sb
i
->
s
_ninodes
)
{
if
(
raw_inode
->
i_mode
==
0
&&
raw_inode
->
i_nlink
==
0
)
{
*
sv_sb_fic_inode
(
sb
,
i
++
)
=
cpu_to_fs16
(
sb
,
ino
);
if
(
i
==
sb
->
sv
_fic_size
)
*
sv_sb_fic_inode
(
sb
,
i
++
)
=
cpu_to_fs16
(
SYSV_SB
(
sb
)
,
ino
);
if
(
i
==
sb
i
->
s
_fic_size
)
break
;
}
if
((
ino
++
&
sb
->
sv
_inodes_per_block_1
)
==
0
)
{
if
((
ino
++
&
sb
i
->
s
_inodes_per_block_1
)
==
0
)
{
brelse
(
bh
);
raw_inode
=
sysv_raw_inode
(
sb
,
ino
,
&
bh
);
if
(
!
raw_inode
)
...
...
@@ -93,7 +97,8 @@ static int refill_free_cache(struct super_block *sb)
void
sysv_free_inode
(
struct
inode
*
inode
)
{
struct
super_block
*
sb
;
struct
super_block
*
sb
=
inode
->
i_sb
;
struct
sysv_sb_info
*
sbi
=
SYSV_SB
(
sb
);
unsigned
int
ino
;
struct
buffer_head
*
bh
;
struct
sysv_inode
*
raw_inode
;
...
...
@@ -101,7 +106,7 @@ void sysv_free_inode(struct inode * inode)
sb
=
inode
->
i_sb
;
ino
=
inode
->
i_ino
;
if
(
ino
<=
SYSV_ROOT_INO
||
ino
>
sb
->
sv
_ninodes
)
{
if
(
ino
<=
SYSV_ROOT_INO
||
ino
>
sb
i
->
s
_ninodes
)
{
printk
(
"sysv_free_inode: inode 0,1,2 or nonexistent inode
\n
"
);
return
;
}
...
...
@@ -113,12 +118,12 @@ void sysv_free_inode(struct inode * inode)
return
;
}
lock_super
(
sb
);
count
=
fs16_to_cpu
(
sb
,
*
sb
->
sv
_sb_fic_count
);
if
(
count
<
sb
->
sv
_fic_size
)
{
*
sv_sb_fic_inode
(
sb
,
count
++
)
=
cpu_to_fs16
(
sb
,
ino
);
*
sb
->
sv_sb_fic_count
=
cpu_to_fs16
(
sb
,
count
);
count
=
fs16_to_cpu
(
sb
i
,
*
sbi
->
s
_sb_fic_count
);
if
(
count
<
sb
i
->
s
_fic_size
)
{
*
sv_sb_fic_inode
(
sb
,
count
++
)
=
cpu_to_fs16
(
sb
i
,
ino
);
*
sb
i
->
s_sb_fic_count
=
cpu_to_fs16
(
sbi
,
count
);
}
fs16_add
(
sb
,
sb
->
sv
_sb_total_free_inodes
,
1
);
fs16_add
(
sb
i
,
sbi
->
s
_sb_total_free_inodes
,
1
);
dirty_sb
(
sb
);
memset
(
raw_inode
,
0
,
sizeof
(
struct
sysv_inode
));
mark_buffer_dirty
(
bh
);
...
...
@@ -128,18 +133,18 @@ void sysv_free_inode(struct inode * inode)
struct
inode
*
sysv_new_inode
(
const
struct
inode
*
dir
,
mode_t
mode
)
{
struct
inode
*
inode
;
struct
super_block
*
sb
;
struct
super_block
*
sb
=
dir
->
i_sb
;
struct
sysv_sb_info
*
sbi
=
SYSV_SB
(
sb
);
struct
inode
*
inode
;
u16
ino
;
unsigned
count
;
sb
=
dir
->
i_sb
;
inode
=
new_inode
(
sb
);
if
(
!
inode
)
return
ERR_PTR
(
-
ENOMEM
);
lock_super
(
sb
);
count
=
fs16_to_cpu
(
sb
,
*
sb
->
sv
_sb_fic_count
);
count
=
fs16_to_cpu
(
sb
i
,
*
sbi
->
s
_sb_fic_count
);
if
(
count
==
0
||
(
*
sv_sb_fic_inode
(
sb
,
count
-
1
)
==
0
))
{
count
=
refill_free_cache
(
sb
);
if
(
count
==
0
)
{
...
...
@@ -150,8 +155,8 @@ struct inode * sysv_new_inode(const struct inode * dir, mode_t mode)
}
/* Now count > 0. */
ino
=
*
sv_sb_fic_inode
(
sb
,
--
count
);
*
sb
->
sv_sb_fic_count
=
cpu_to_fs16
(
sb
,
count
);
fs16_add
(
sb
,
sb
->
sv
_sb_total_free_inodes
,
-
1
);
*
sb
i
->
s_sb_fic_count
=
cpu_to_fs16
(
sbi
,
count
);
fs16_add
(
sb
i
,
sbi
->
s
_sb_total_free_inodes
,
-
1
);
dirty_sb
(
sb
);
if
(
dir
->
i_mode
&
S_ISGID
)
{
...
...
@@ -162,7 +167,7 @@ struct inode * sysv_new_inode(const struct inode * dir, mode_t mode)
inode
->
i_gid
=
current
->
fsgid
;
inode
->
i_uid
=
current
->
fsuid
;
inode
->
i_ino
=
fs16_to_cpu
(
sb
,
ino
);
inode
->
i_ino
=
fs16_to_cpu
(
sb
i
,
ino
);
inode
->
i_mtime
=
inode
->
i_atime
=
inode
->
i_ctime
=
CURRENT_TIME
;
inode
->
i_blocks
=
inode
->
i_blksize
=
0
;
memset
(
SYSV_I
(
inode
)
->
i_data
,
0
,
sizeof
(
SYSV_I
(
inode
)
->
i_data
));
...
...
@@ -180,13 +185,14 @@ struct inode * sysv_new_inode(const struct inode * dir, mode_t mode)
unsigned
long
sysv_count_free_inodes
(
struct
super_block
*
sb
)
{
struct
sysv_sb_info
*
sbi
=
SYSV_SB
(
sb
);
struct
buffer_head
*
bh
;
struct
sysv_inode
*
raw_inode
;
int
ino
,
count
,
sb_count
;
lock_super
(
sb
);
sb_count
=
fs16_to_cpu
(
sb
,
*
sb
->
sv
_sb_total_free_inodes
);
sb_count
=
fs16_to_cpu
(
sb
i
,
*
sbi
->
s
_sb_total_free_inodes
);
if
(
0
)
goto
trust_sb
;
...
...
@@ -197,10 +203,10 @@ unsigned long sysv_count_free_inodes(struct super_block * sb)
raw_inode
=
sysv_raw_inode
(
sb
,
ino
,
&
bh
);
if
(
!
raw_inode
)
goto
Eio
;
while
(
ino
<=
sb
->
sv
_ninodes
)
{
while
(
ino
<=
sb
i
->
s
_ninodes
)
{
if
(
raw_inode
->
i_mode
==
0
&&
raw_inode
->
i_nlink
==
0
)
count
++
;
if
((
ino
++
&
sb
->
sv
_inodes_per_block_1
)
==
0
)
{
if
((
ino
++
&
sb
i
->
s
_inodes_per_block_1
)
==
0
)
{
brelse
(
bh
);
raw_inode
=
sysv_raw_inode
(
sb
,
ino
,
&
bh
);
if
(
!
raw_inode
)
...
...
@@ -220,7 +226,7 @@ unsigned long sysv_count_free_inodes(struct super_block * sb)
"free inode count was %d, correcting to %d
\n
"
,
sb_count
,
count
);
if
(
!
(
sb
->
s_flags
&
MS_RDONLY
))
{
*
sb
->
sv_sb_total_free_inodes
=
cpu_to_fs16
(
sb
,
count
);
*
sb
i
->
s_sb_total_free_inodes
=
cpu_to_fs16
(
SYSV_SB
(
sb
)
,
count
);
dirty_sb
(
sb
);
}
goto
out
;
...
...
fs/sysv/inode.c
View file @
84f922f1
...
...
@@ -21,56 +21,68 @@
* the superblock.
*/
#include <linux/fs.h>
#include <linux/sysv_fs.h>
#include <linux/locks.h>
#include <linux/smp_lock.h>
#include <linux/highuid.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <asm/byteorder.h>
#include "sysv.h"
/* This is only called on sync() and umount(), when s_dirt=1. */
static
void
sysv_write_super
(
struct
super_block
*
sb
)
{
struct
sysv_sb_info
*
sbi
=
SYSV_SB
(
sb
);
unsigned
long
time
=
CURRENT_TIME
,
old_time
;
lock_kernel
();
if
(
!
(
sb
->
s_flags
&
MS_RDONLY
))
{
/* If we are going to write out the super block,
then attach current time stamp.
But if the filesystem was marked clean, keep it clean. */
unsigned
long
time
=
CURRENT_TIME
;
unsigned
long
old_time
=
fs32_to_cpu
(
sb
,
*
sb
->
sv_sb_time
);
if
(
sb
->
sv_type
==
FSTYPE_SYSV4
)
if
(
*
sb
->
sv_sb_state
==
cpu_to_fs32
(
sb
,
0x7c269d38
-
old_time
))
*
sb
->
sv_sb_state
=
cpu_to_fs32
(
sb
,
0x7c269d38
-
time
);
*
sb
->
sv_sb_time
=
cpu_to_fs32
(
sb
,
time
);
mark_buffer_dirty
(
sb
->
sv_bh2
);
if
(
sb
->
s_flags
&
MS_RDONLY
)
goto
clean
;
/*
* If we are going to write out the super block,
* then attach current time stamp.
* But if the filesystem was marked clean, keep it clean.
*/
old_time
=
fs32_to_cpu
(
sbi
,
*
sbi
->
s_sb_time
);
if
(
sbi
->
s_type
==
FSTYPE_SYSV4
)
{
if
(
*
sbi
->
s_sb_state
==
cpu_to_fs32
(
sbi
,
0x7c269d38
-
old_time
))
*
sbi
->
s_sb_state
=
cpu_to_fs32
(
sbi
,
0x7c269d38
-
time
);
*
sbi
->
s_sb_time
=
cpu_to_fs32
(
sbi
,
time
);
mark_buffer_dirty
(
sbi
->
s_bh2
);
}
clean:
sb
->
s_dirt
=
0
;
unlock_kernel
();
}
static
void
sysv_put_super
(
struct
super_block
*
sb
)
{
struct
sysv_sb_info
*
sbi
=
SYSV_SB
(
sb
);
if
(
!
(
sb
->
s_flags
&
MS_RDONLY
))
{
/* XXX ext2 also updates the state here */
mark_buffer_dirty
(
sb
->
sv
_bh1
);
if
(
sb
->
sv_bh1
!=
sb
->
sv
_bh2
)
mark_buffer_dirty
(
sb
->
sv
_bh2
);
mark_buffer_dirty
(
sb
i
->
s
_bh1
);
if
(
sb
i
->
s_bh1
!=
sbi
->
s
_bh2
)
mark_buffer_dirty
(
sb
i
->
s
_bh2
);
}
brelse
(
sb
->
sv_bh1
);
if
(
sb
->
sv_bh1
!=
sb
->
sv_bh2
)
brelse
(
sb
->
sv_bh2
);
brelse
(
sbi
->
s_bh1
);
if
(
sbi
->
s_bh1
!=
sbi
->
s_bh2
)
brelse
(
sbi
->
s_bh2
);
kfree
(
sbi
);
}
static
int
sysv_statfs
(
struct
super_block
*
sb
,
struct
statfs
*
buf
)
{
struct
sysv_sb_info
*
sbi
=
SYSV_SB
(
sb
);
buf
->
f_type
=
sb
->
s_magic
;
buf
->
f_bsize
=
sb
->
s_blocksize
;
buf
->
f_blocks
=
sb
->
sv
_ndatazones
;
buf
->
f_blocks
=
sb
i
->
s
_ndatazones
;
buf
->
f_bavail
=
buf
->
f_bfree
=
sysv_count_free_blocks
(
sb
);
buf
->
f_files
=
sb
->
sv
_ninodes
;
buf
->
f_files
=
sb
i
->
s
_ninodes
;
buf
->
f_ffree
=
sysv_count_free_inodes
(
sb
);
buf
->
f_namelen
=
SYSV_NAMELEN
;
return
0
;
...
...
@@ -79,15 +91,15 @@ static int sysv_statfs(struct super_block *sb, struct statfs *buf)
/*
* NXI <-> N0XI for PDP, XIN <-> XIN0 for le32, NIX <-> 0NIX for be32
*/
static
inline
void
read3byte
(
struct
s
uper_block
*
sb
,
static
inline
void
read3byte
(
struct
s
ysv_sb_info
*
sbi
,
unsigned
char
*
from
,
unsigned
char
*
to
)
{
if
(
sb
->
sv
_bytesex
==
BYTESEX_PDP
)
{
if
(
sb
i
->
s
_bytesex
==
BYTESEX_PDP
)
{
to
[
0
]
=
from
[
0
];
to
[
1
]
=
0
;
to
[
2
]
=
from
[
1
];
to
[
3
]
=
from
[
2
];
}
else
if
(
sb
->
sv
_bytesex
==
BYTESEX_LE
)
{
}
else
if
(
sb
i
->
s
_bytesex
==
BYTESEX_LE
)
{
to
[
0
]
=
from
[
0
];
to
[
1
]
=
from
[
1
];
to
[
2
]
=
from
[
2
];
...
...
@@ -100,14 +112,14 @@ static inline void read3byte(struct super_block *sb,
}
}
static
inline
void
write3byte
(
struct
s
uper_block
*
sb
,
static
inline
void
write3byte
(
struct
s
ysv_sb_info
*
sbi
,
unsigned
char
*
from
,
unsigned
char
*
to
)
{
if
(
sb
->
sv
_bytesex
==
BYTESEX_PDP
)
{
if
(
sb
i
->
s
_bytesex
==
BYTESEX_PDP
)
{
to
[
0
]
=
from
[
0
];
to
[
1
]
=
from
[
2
];
to
[
2
]
=
from
[
3
];
}
else
if
(
sb
->
sv
_bytesex
==
BYTESEX_LE
)
{
}
else
if
(
sb
i
->
s
_bytesex
==
BYTESEX_LE
)
{
to
[
0
]
=
from
[
0
];
to
[
1
]
=
from
[
1
];
to
[
2
]
=
from
[
2
];
...
...
@@ -146,6 +158,7 @@ void sysv_set_inode(struct inode *inode, dev_t rdev)
static
void
sysv_read_inode
(
struct
inode
*
inode
)
{
struct
super_block
*
sb
=
inode
->
i_sb
;
struct
sysv_sb_info
*
sbi
=
SYSV_SB
(
sb
);
struct
buffer_head
*
bh
;
struct
sysv_inode
*
raw_inode
;
struct
sysv_inode_info
*
si
;
...
...
@@ -153,7 +166,7 @@ static void sysv_read_inode(struct inode *inode)
dev_t
rdev
=
0
;
ino
=
inode
->
i_ino
;
if
(
!
ino
||
ino
>
sb
->
sv
_ninodes
)
{
if
(
!
ino
||
ino
>
sb
i
->
s
_ninodes
)
{
printk
(
"Bad inode number on dev %s: %d is out of range
\n
"
,
inode
->
i_sb
->
s_id
,
ino
);
goto
bad_inode
;
...
...
@@ -165,23 +178,23 @@ static void sysv_read_inode(struct inode *inode)
goto
bad_inode
;
}
/* SystemV FS: kludge permissions if ino==SYSV_ROOT_INO ?? */
inode
->
i_mode
=
fs16_to_cpu
(
sb
,
raw_inode
->
i_mode
);
inode
->
i_uid
=
(
uid_t
)
fs16_to_cpu
(
sb
,
raw_inode
->
i_uid
);
inode
->
i_gid
=
(
gid_t
)
fs16_to_cpu
(
sb
,
raw_inode
->
i_gid
);
inode
->
i_nlink
=
fs16_to_cpu
(
sb
,
raw_inode
->
i_nlink
);
inode
->
i_size
=
fs32_to_cpu
(
sb
,
raw_inode
->
i_size
);
inode
->
i_atime
=
fs32_to_cpu
(
sb
,
raw_inode
->
i_atime
);
inode
->
i_mtime
=
fs32_to_cpu
(
sb
,
raw_inode
->
i_mtime
);
inode
->
i_ctime
=
fs32_to_cpu
(
sb
,
raw_inode
->
i_ctime
);
inode
->
i_mode
=
fs16_to_cpu
(
sb
i
,
raw_inode
->
i_mode
);
inode
->
i_uid
=
(
uid_t
)
fs16_to_cpu
(
sb
i
,
raw_inode
->
i_uid
);
inode
->
i_gid
=
(
gid_t
)
fs16_to_cpu
(
sb
i
,
raw_inode
->
i_gid
);
inode
->
i_nlink
=
fs16_to_cpu
(
sb
i
,
raw_inode
->
i_nlink
);
inode
->
i_size
=
fs32_to_cpu
(
sb
i
,
raw_inode
->
i_size
);
inode
->
i_atime
=
fs32_to_cpu
(
sb
i
,
raw_inode
->
i_atime
);
inode
->
i_mtime
=
fs32_to_cpu
(
sb
i
,
raw_inode
->
i_mtime
);
inode
->
i_ctime
=
fs32_to_cpu
(
sb
i
,
raw_inode
->
i_ctime
);
inode
->
i_blocks
=
inode
->
i_blksize
=
0
;
si
=
SYSV_I
(
inode
);
for
(
block
=
0
;
block
<
10
+
1
+
1
+
1
;
block
++
)
read3byte
(
sb
,
&
raw_inode
->
i_a
.
i_addb
[
3
*
block
],
(
unsigned
char
*
)
&
si
->
i_data
[
block
]);
read3byte
(
sb
i
,
&
raw_inode
->
i_data
[
3
*
block
],
(
u8
*
)
&
si
->
i_data
[
block
]);
brelse
(
bh
);
if
(
S_ISCHR
(
inode
->
i_mode
)
||
S_ISBLK
(
inode
->
i_mode
))
rdev
=
(
u16
)
fs32_to_cpu
(
sb
,
si
->
i_data
[
0
]);
rdev
=
(
u16
)
fs32_to_cpu
(
sb
i
,
si
->
i_data
[
0
]);
si
->
i_dir_start_lookup
=
0
;
sysv_set_inode
(
inode
,
rdev
);
return
;
...
...
@@ -194,13 +207,14 @@ static void sysv_read_inode(struct inode *inode)
static
struct
buffer_head
*
sysv_update_inode
(
struct
inode
*
inode
)
{
struct
super_block
*
sb
=
inode
->
i_sb
;
struct
sysv_sb_info
*
sbi
=
SYSV_SB
(
sb
);
struct
buffer_head
*
bh
;
struct
sysv_inode
*
raw_inode
;
struct
sysv_inode_info
*
si
;
unsigned
int
ino
,
block
;
ino
=
inode
->
i_ino
;
if
(
!
ino
||
ino
>
sb
->
sv
_ninodes
)
{
if
(
!
ino
||
ino
>
sb
i
->
s
_ninodes
)
{
printk
(
"Bad inode number on dev %s: %d is out of range
\n
"
,
inode
->
i_sb
->
s_id
,
ino
);
return
0
;
...
...
@@ -211,21 +225,21 @@ static struct buffer_head * sysv_update_inode(struct inode * inode)
return
0
;
}
raw_inode
->
i_mode
=
cpu_to_fs16
(
sb
,
inode
->
i_mode
);
raw_inode
->
i_uid
=
cpu_to_fs16
(
sb
,
fs_high2lowuid
(
inode
->
i_uid
));
raw_inode
->
i_gid
=
cpu_to_fs16
(
sb
,
fs_high2lowgid
(
inode
->
i_gid
));
raw_inode
->
i_nlink
=
cpu_to_fs16
(
sb
,
inode
->
i_nlink
);
raw_inode
->
i_size
=
cpu_to_fs32
(
sb
,
inode
->
i_size
);
raw_inode
->
i_atime
=
cpu_to_fs32
(
sb
,
inode
->
i_atime
);
raw_inode
->
i_mtime
=
cpu_to_fs32
(
sb
,
inode
->
i_mtime
);
raw_inode
->
i_ctime
=
cpu_to_fs32
(
sb
,
inode
->
i_ctime
);
raw_inode
->
i_mode
=
cpu_to_fs16
(
sb
i
,
inode
->
i_mode
);
raw_inode
->
i_uid
=
cpu_to_fs16
(
sb
i
,
fs_high2lowuid
(
inode
->
i_uid
));
raw_inode
->
i_gid
=
cpu_to_fs16
(
sb
i
,
fs_high2lowgid
(
inode
->
i_gid
));
raw_inode
->
i_nlink
=
cpu_to_fs16
(
sb
i
,
inode
->
i_nlink
);
raw_inode
->
i_size
=
cpu_to_fs32
(
sb
i
,
inode
->
i_size
);
raw_inode
->
i_atime
=
cpu_to_fs32
(
sb
i
,
inode
->
i_atime
);
raw_inode
->
i_mtime
=
cpu_to_fs32
(
sb
i
,
inode
->
i_mtime
);
raw_inode
->
i_ctime
=
cpu_to_fs32
(
sb
i
,
inode
->
i_ctime
);
si
=
SYSV_I
(
inode
);
if
(
S_ISCHR
(
inode
->
i_mode
)
||
S_ISBLK
(
inode
->
i_mode
))
si
->
i_data
[
0
]
=
cpu_to_fs32
(
sb
,
kdev_t_to_nr
(
inode
->
i_rdev
));
si
->
i_data
[
0
]
=
cpu_to_fs32
(
sb
i
,
kdev_t_to_nr
(
inode
->
i_rdev
));
for
(
block
=
0
;
block
<
10
+
1
+
1
+
1
;
block
++
)
write3byte
(
sb
,
(
unsigned
char
*
)
&
si
->
i_data
[
block
],
&
raw_inode
->
i_
a
.
i_addb
[
3
*
block
]);
write3byte
(
sb
i
,
(
u8
*
)
&
si
->
i_data
[
block
],
&
raw_inode
->
i_
data
[
3
*
block
]);
mark_buffer_dirty
(
bh
);
return
bh
;
}
...
...
fs/sysv/itree.c
View file @
84f922f1
...
...
@@ -5,10 +5,8 @@
* AV, Sep--Dec 2000
*/
#include <linux/fs.h>
#include <linux/sysv_fs.h>
#include <linux/locks.h>
#include
<linux/smp_lock.h>
#include
"sysv.h"
enum
{
DIRECT
=
10
,
DEPTH
=
4
};
/* Have triple indirect */
...
...
@@ -24,9 +22,10 @@ static inline void dirty_indirect(struct buffer_head *bh, struct inode *inode)
static
int
block_to_path
(
struct
inode
*
inode
,
long
block
,
int
offsets
[
DEPTH
])
{
struct
super_block
*
sb
=
inode
->
i_sb
;
int
ptrs_bits
=
sb
->
sv_ind_per_block_bits
;
unsigned
long
indirect_blocks
=
sb
->
sv_ind_per_block
,
double_blocks
=
sb
->
sv_ind_per_block_2
;
struct
sysv_sb_info
*
sbi
=
SYSV_SB
(
sb
);
int
ptrs_bits
=
sbi
->
s_ind_per_block_bits
;
unsigned
long
indirect_blocks
=
sbi
->
s_ind_per_block
,
double_blocks
=
sbi
->
s_ind_per_block_2
;
int
n
=
0
;
if
(
block
<
0
)
{
...
...
@@ -51,9 +50,9 @@ static int block_to_path(struct inode *inode, long block, int offsets[DEPTH])
return
n
;
}
static
inline
int
block_to_cpu
(
struct
s
uper_block
*
sb
,
u32
nr
)
static
inline
int
block_to_cpu
(
struct
s
ysv_sb_info
*
sbi
,
u32
nr
)
{
return
sb
->
sv_block_base
+
fs32_to_cpu
(
sb
,
nr
);
return
sb
i
->
s_block_base
+
fs32_to_cpu
(
sbi
,
nr
);
}
typedef
struct
{
...
...
@@ -62,6 +61,8 @@ typedef struct {
struct
buffer_head
*
bh
;
}
Indirect
;
static
rwlock_t
pointers_lock
=
RW_LOCK_UNLOCKED
;
static
inline
void
add_chain
(
Indirect
*
p
,
struct
buffer_head
*
bh
,
u32
*
v
)
{
p
->
key
=
*
(
p
->
p
=
v
);
...
...
@@ -91,23 +92,26 @@ static Indirect *get_branch(struct inode *inode,
struct
buffer_head
*
bh
;
*
err
=
0
;
add_chain
(
chain
,
NULL
,
SYSV_I
(
inode
)
->
i_data
+
*
offsets
);
add_chain
(
chain
,
NULL
,
SYSV_I
(
inode
)
->
i_data
+
*
offsets
);
if
(
!
p
->
key
)
goto
no_block
;
while
(
--
depth
)
{
int
block
=
block_to_cpu
(
sb
,
p
->
key
);
int
block
=
block_to_cpu
(
SYSV_SB
(
sb
)
,
p
->
key
);
bh
=
sb_bread
(
sb
,
block
);
if
(
!
bh
)
goto
failure
;
read_lock
(
&
pointers_lock
);
if
(
!
verify_chain
(
chain
,
p
))
goto
changed
;
add_chain
(
++
p
,
bh
,
(
u32
*
)
bh
->
b_data
+
*++
offsets
);
read_unlock
(
&
pointers_lock
);
if
(
!
p
->
key
)
goto
no_block
;
goto
no_block
;
}
return
NULL
;
changed:
read_unlock
(
&
pointers_lock
);
brelse
(
bh
);
*
err
=
-
EAGAIN
;
goto
no_block
;
...
...
@@ -138,7 +142,7 @@ static int alloc_branch(struct inode *inode,
* Get buffer_head for parent block, zero it out and set
* the pointer to new one, then send parent to disk.
*/
parent
=
block_to_cpu
(
inode
->
i_sb
,
branch
[
n
-
1
].
key
);
parent
=
block_to_cpu
(
SYSV_SB
(
inode
->
i_sb
)
,
branch
[
n
-
1
].
key
);
bh
=
sb_getblk
(
inode
->
i_sb
,
parent
);
lock_buffer
(
bh
);
memset
(
bh
->
b_data
,
0
,
blocksize
);
...
...
@@ -166,12 +170,14 @@ static inline int splice_branch(struct inode *inode,
int
num
)
{
int
i
;
/* Verify that place we are splicing to is still there and vacant */
/* Verify that place we are splicing to is still there and vacant */
write_lock
(
&
pointers_lock
);
if
(
!
verify_chain
(
chain
,
where
-
1
)
||
*
where
->
p
)
goto
changed
;
*
where
->
p
=
where
->
key
;
write_unlock
(
&
pointers_lock
);
inode
->
i_ctime
=
CURRENT_TIME
;
/* had we spliced it onto indirect block? */
...
...
@@ -185,6 +191,7 @@ static inline int splice_branch(struct inode *inode,
return
0
;
changed:
write_unlock
(
&
pointers_lock
);
for
(
i
=
1
;
i
<
num
;
i
++
)
bforget
(
where
[
i
].
bh
);
for
(
i
=
0
;
i
<
num
;
i
++
)
...
...
@@ -205,14 +212,14 @@ static int get_block(struct inode *inode, sector_t iblock, struct buffer_head *b
if
(
depth
==
0
)
goto
out
;
lock_kernel
();
reread:
partial
=
get_branch
(
inode
,
depth
,
offsets
,
chain
,
&
err
);
/* Simplest case - block found, no allocation needed */
if
(
!
partial
)
{
got_it:
map_bh
(
bh_result
,
sb
,
block_to_cpu
(
sb
,
chain
[
depth
-
1
].
key
));
map_bh
(
bh_result
,
sb
,
block_to_cpu
(
SYSV_SB
(
sb
),
chain
[
depth
-
1
].
key
));
/* Clean up and exit */
partial
=
chain
+
depth
-
1
;
/* the whole chain */
goto
cleanup
;
...
...
@@ -225,7 +232,6 @@ static int get_block(struct inode *inode, sector_t iblock, struct buffer_head *b
brelse
(
partial
->
bh
);
partial
--
;
}
unlock_kernel
();
out:
return
err
;
}
...
...
@@ -277,6 +283,8 @@ static Indirect *find_shared(struct inode *inode,
*
top
=
0
;
for
(
k
=
depth
;
k
>
1
&&
!
offsets
[
k
-
1
];
k
--
)
;
write_lock
(
&
pointers_lock
);
partial
=
get_branch
(
inode
,
k
,
offsets
,
chain
,
&
err
);
if
(
!
partial
)
partial
=
chain
+
k
-
1
;
...
...
@@ -284,8 +292,10 @@ static Indirect *find_shared(struct inode *inode,
* If the branch acquired continuation since we've looked at it -
* fine, it should all survive and (new) top doesn't belong to us.
*/
if
(
!
partial
->
key
&&
*
partial
->
p
)
if
(
!
partial
->
key
&&
*
partial
->
p
)
{
write_unlock
(
&
pointers_lock
);
goto
no_top
;
}
for
(
p
=
partial
;
p
>
chain
&&
all_zeroes
((
u32
*
)
p
->
bh
->
b_data
,
p
->
p
);
p
--
)
;
/*
...
...
@@ -300,8 +310,9 @@ static Indirect *find_shared(struct inode *inode,
*
top
=
*
p
->
p
;
*
p
->
p
=
0
;
}
write_unlock
(
&
pointers_lock
);
while
(
partial
>
p
)
{
while
(
partial
>
p
)
{
brelse
(
partial
->
bh
);
partial
--
;
}
...
...
@@ -333,7 +344,7 @@ static void free_branches(struct inode *inode, u32 *p, u32 *q, int depth)
if
(
!
nr
)
continue
;
*
p
=
0
;
block
=
block_to_cpu
(
sb
,
nr
);
block
=
block_to_cpu
(
SYSV_SB
(
sb
)
,
nr
);
bh
=
sb_bread
(
sb
,
block
);
if
(
!
bh
)
continue
;
...
...
@@ -372,8 +383,6 @@ void sysv_truncate (struct inode * inode)
if
(
n
==
0
)
return
;
lock_kernel
();
if
(
n
==
1
)
{
free_data
(
inode
,
i_data
+
offsets
[
0
],
i_data
+
DIRECT
);
goto
do_indirects
;
...
...
@@ -412,7 +421,6 @@ void sysv_truncate (struct inode * inode)
sysv_sync_inode
(
inode
);
else
mark_inode_dirty
(
inode
);
unlock_kernel
();
}
static
int
sysv_writepage
(
struct
page
*
page
)
...
...
fs/sysv/namei.c
View file @
84f922f1
...
...
@@ -12,10 +12,9 @@
* Copyright (C) 1997, 1998 Krzysztof G. Baranowski
*/
#include <linux/fs.h>
#include <linux/sysv_fs.h>
#include <linux/pagemap.h>
#include <linux/smp_lock.h>
#include "sysv.h"
static
inline
void
inc_count
(
struct
inode
*
inode
)
{
...
...
@@ -138,7 +137,7 @@ static int sysv_link(struct dentry * old_dentry, struct inode * dir,
{
struct
inode
*
inode
=
old_dentry
->
d_inode
;
if
(
inode
->
i_nlink
>=
inode
->
i_sb
->
sv
_link_max
)
if
(
inode
->
i_nlink
>=
SYSV_SB
(
inode
->
i_sb
)
->
s
_link_max
)
return
-
EMLINK
;
inode
->
i_ctime
=
CURRENT_TIME
;
...
...
@@ -153,7 +152,7 @@ static int sysv_mkdir(struct inode * dir, struct dentry *dentry, int mode)
struct
inode
*
inode
;
int
err
=
-
EMLINK
;
if
(
dir
->
i_nlink
>=
dir
->
i_sb
->
sv
_link_max
)
if
(
dir
->
i_nlink
>=
SYSV_SB
(
dir
->
i_sb
)
->
s
_link_max
)
goto
out
;
inc_count
(
dir
);
...
...
@@ -271,7 +270,7 @@ static int sysv_rename(struct inode * old_dir, struct dentry * old_dentry,
}
else
{
if
(
dir_de
)
{
err
=
-
EMLINK
;
if
(
new_dir
->
i_nlink
>=
new_dir
->
i_sb
->
sv
_link_max
)
if
(
new_dir
->
i_nlink
>=
SYSV_SB
(
new_dir
->
i_sb
)
->
s
_link_max
)
goto
out_dir
;
}
inc_count
(
old_inode
);
...
...
fs/sysv/super.c
View file @
84f922f1
...
...
@@ -21,10 +21,9 @@
*/
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/sysv_fs.h>
#include <linux/init.h>
#include <linux/slab.h>
#include "sysv.h"
/*
* The following functions try to recognize specific filesystems.
...
...
@@ -44,10 +43,10 @@ enum {
JAN_1_1980
=
(
10
*
365
+
2
)
*
24
*
60
*
60
};
static
void
detected_xenix
(
struct
s
uper_block
*
sb
)
static
void
detected_xenix
(
struct
s
ysv_sb_info
*
sbi
)
{
struct
buffer_head
*
bh1
=
sb
->
sv
_bh1
;
struct
buffer_head
*
bh2
=
sb
->
sv
_bh2
;
struct
buffer_head
*
bh1
=
sb
i
->
s
_bh1
;
struct
buffer_head
*
bh2
=
sb
i
->
s
_bh2
;
struct
xenix_super_block
*
sbd1
;
struct
xenix_super_block
*
sbd2
;
...
...
@@ -59,152 +58,153 @@ static void detected_xenix(struct super_block *sb)
sbd2
=
(
struct
xenix_super_block
*
)
(
bh2
->
b_data
-
512
);
}
sb
->
sv
_link_max
=
XENIX_LINK_MAX
;
sb
->
sv
_fic_size
=
XENIX_NICINOD
;
sb
->
sv
_flc_size
=
XENIX_NICFREE
;
sb
->
sv_sbd1
=
(
char
*
)
sbd1
;
sb
->
sv_sbd2
=
(
char
*
)
sbd2
;
sb
->
sv
_sb_fic_count
=
&
sbd1
->
s_ninode
;
sb
->
sv
_sb_fic_inodes
=
&
sbd1
->
s_inode
[
0
];
sb
->
sv
_sb_total_free_inodes
=
&
sbd2
->
s_tinode
;
sb
->
sv
_bcache_count
=
&
sbd1
->
s_nfree
;
sb
->
sv
_bcache
=
&
sbd1
->
s_free
[
0
];
sb
->
sv
_free_blocks
=
&
sbd2
->
s_tfree
;
sb
->
sv
_sb_time
=
&
sbd2
->
s_time
;
sb
->
sv_firstdatazone
=
fs16_to_cpu
(
sb
,
sbd1
->
s_isize
);
sb
->
sv_nzones
=
fs32_to_cpu
(
sb
,
sbd1
->
s_fsize
);
sb
i
->
s
_link_max
=
XENIX_LINK_MAX
;
sb
i
->
s
_fic_size
=
XENIX_NICINOD
;
sb
i
->
s
_flc_size
=
XENIX_NICFREE
;
sb
i
->
s_sbd1
=
(
char
*
)
sbd1
;
sb
i
->
s_sbd2
=
(
char
*
)
sbd2
;
sb
i
->
s
_sb_fic_count
=
&
sbd1
->
s_ninode
;
sb
i
->
s
_sb_fic_inodes
=
&
sbd1
->
s_inode
[
0
];
sb
i
->
s
_sb_total_free_inodes
=
&
sbd2
->
s_tinode
;
sb
i
->
s
_bcache_count
=
&
sbd1
->
s_nfree
;
sb
i
->
s
_bcache
=
&
sbd1
->
s_free
[
0
];
sb
i
->
s
_free_blocks
=
&
sbd2
->
s_tfree
;
sb
i
->
s
_sb_time
=
&
sbd2
->
s_time
;
sb
i
->
s_firstdatazone
=
fs16_to_cpu
(
sbi
,
sbd1
->
s_isize
);
sb
i
->
s_nzones
=
fs32_to_cpu
(
sbi
,
sbd1
->
s_fsize
);
}
static
void
detected_sysv4
(
struct
s
uper_block
*
sb
)
static
void
detected_sysv4
(
struct
s
ysv_sb_info
*
sbi
)
{
struct
sysv4_super_block
*
sbd
;
struct
buffer_head
*
bh1
=
sb
->
sv
_bh1
;
struct
buffer_head
*
bh2
=
sb
->
sv
_bh2
;
struct
buffer_head
*
bh1
=
sb
i
->
s
_bh1
;
struct
buffer_head
*
bh2
=
sb
i
->
s
_bh2
;
if
(
bh1
==
bh2
)
sbd
=
(
struct
sysv4_super_block
*
)
(
bh1
->
b_data
+
BLOCK_SIZE
/
2
);
else
sbd
=
(
struct
sysv4_super_block
*
)
bh2
->
b_data
;
sb
->
sv
_link_max
=
SYSV_LINK_MAX
;
sb
->
sv
_fic_size
=
SYSV_NICINOD
;
sb
->
sv
_flc_size
=
SYSV_NICFREE
;
sb
->
sv_sbd1
=
(
char
*
)
sbd
;
sb
->
sv_sbd2
=
(
char
*
)
sbd
;
sb
->
sv
_sb_fic_count
=
&
sbd
->
s_ninode
;
sb
->
sv
_sb_fic_inodes
=
&
sbd
->
s_inode
[
0
];
sb
->
sv
_sb_total_free_inodes
=
&
sbd
->
s_tinode
;
sb
->
sv
_bcache_count
=
&
sbd
->
s_nfree
;
sb
->
sv
_bcache
=
&
sbd
->
s_free
[
0
];
sb
->
sv
_free_blocks
=
&
sbd
->
s_tfree
;
sb
->
sv
_sb_time
=
&
sbd
->
s_time
;
sb
->
sv
_sb_state
=
&
sbd
->
s_state
;
sb
->
sv_firstdatazone
=
fs16_to_cpu
(
sb
,
sbd
->
s_isize
);
sb
->
sv_nzones
=
fs32_to_cpu
(
sb
,
sbd
->
s_fsize
);
sb
i
->
s
_link_max
=
SYSV_LINK_MAX
;
sb
i
->
s
_fic_size
=
SYSV_NICINOD
;
sb
i
->
s
_flc_size
=
SYSV_NICFREE
;
sb
i
->
s_sbd1
=
(
char
*
)
sbd
;
sb
i
->
s_sbd2
=
(
char
*
)
sbd
;
sb
i
->
s
_sb_fic_count
=
&
sbd
->
s_ninode
;
sb
i
->
s
_sb_fic_inodes
=
&
sbd
->
s_inode
[
0
];
sb
i
->
s
_sb_total_free_inodes
=
&
sbd
->
s_tinode
;
sb
i
->
s
_bcache_count
=
&
sbd
->
s_nfree
;
sb
i
->
s
_bcache
=
&
sbd
->
s_free
[
0
];
sb
i
->
s
_free_blocks
=
&
sbd
->
s_tfree
;
sb
i
->
s
_sb_time
=
&
sbd
->
s_time
;
sb
i
->
s
_sb_state
=
&
sbd
->
s_state
;
sb
i
->
s_firstdatazone
=
fs16_to_cpu
(
sbi
,
sbd
->
s_isize
);
sb
i
->
s_nzones
=
fs32_to_cpu
(
sbi
,
sbd
->
s_fsize
);
}
static
void
detected_sysv2
(
struct
s
uper_block
*
sb
)
static
void
detected_sysv2
(
struct
s
ysv_sb_info
*
sbi
)
{
struct
sysv2_super_block
*
sbd
;
struct
buffer_head
*
bh1
=
sb
->
sv
_bh1
;
struct
buffer_head
*
bh2
=
sb
->
sv
_bh2
;
struct
sysv2_super_block
*
sbd
;
struct
buffer_head
*
bh1
=
sb
i
->
s
_bh1
;
struct
buffer_head
*
bh2
=
sb
i
->
s
_bh2
;
if
(
bh1
==
bh2
)
sbd
=
(
struct
sysv2_super_block
*
)
(
bh1
->
b_data
+
BLOCK_SIZE
/
2
);
else
sbd
=
(
struct
sysv2_super_block
*
)
bh2
->
b_data
;
sb
->
sv
_link_max
=
SYSV_LINK_MAX
;
sb
->
sv
_fic_size
=
SYSV_NICINOD
;
sb
->
sv
_flc_size
=
SYSV_NICFREE
;
sb
->
sv_sbd1
=
(
char
*
)
sbd
;
sb
->
sv_sbd2
=
(
char
*
)
sbd
;
sb
->
sv
_sb_fic_count
=
&
sbd
->
s_ninode
;
sb
->
sv
_sb_fic_inodes
=
&
sbd
->
s_inode
[
0
];
sb
->
sv
_sb_total_free_inodes
=
&
sbd
->
s_tinode
;
sb
->
sv
_bcache_count
=
&
sbd
->
s_nfree
;
sb
->
sv
_bcache
=
&
sbd
->
s_free
[
0
];
sb
->
sv
_free_blocks
=
&
sbd
->
s_tfree
;
sb
->
sv
_sb_time
=
&
sbd
->
s_time
;
sb
->
sv
_sb_state
=
&
sbd
->
s_state
;
sb
->
sv_firstdatazone
=
fs16_to_cpu
(
sb
,
sbd
->
s_isize
);
sb
->
sv_nzones
=
fs32_to_cpu
(
sb
,
sbd
->
s_fsize
);
sb
i
->
s
_link_max
=
SYSV_LINK_MAX
;
sb
i
->
s
_fic_size
=
SYSV_NICINOD
;
sb
i
->
s
_flc_size
=
SYSV_NICFREE
;
sb
i
->
s_sbd1
=
(
char
*
)
sbd
;
sb
i
->
s_sbd2
=
(
char
*
)
sbd
;
sb
i
->
s
_sb_fic_count
=
&
sbd
->
s_ninode
;
sb
i
->
s
_sb_fic_inodes
=
&
sbd
->
s_inode
[
0
];
sb
i
->
s
_sb_total_free_inodes
=
&
sbd
->
s_tinode
;
sb
i
->
s
_bcache_count
=
&
sbd
->
s_nfree
;
sb
i
->
s
_bcache
=
&
sbd
->
s_free
[
0
];
sb
i
->
s
_free_blocks
=
&
sbd
->
s_tfree
;
sb
i
->
s
_sb_time
=
&
sbd
->
s_time
;
sb
i
->
s
_sb_state
=
&
sbd
->
s_state
;
sb
i
->
s_firstdatazone
=
fs16_to_cpu
(
sbi
,
sbd
->
s_isize
);
sb
i
->
s_nzones
=
fs32_to_cpu
(
sbi
,
sbd
->
s_fsize
);
}
static
void
detected_coherent
(
struct
s
uper_block
*
sb
)
static
void
detected_coherent
(
struct
s
ysv_sb_info
*
sbi
)
{
struct
coh_super_block
*
sbd
;
struct
buffer_head
*
bh1
=
sb
->
sv
_bh1
;
struct
buffer_head
*
bh1
=
sb
i
->
s
_bh1
;
sbd
=
(
struct
coh_super_block
*
)
bh1
->
b_data
;
sb
->
sv
_link_max
=
COH_LINK_MAX
;
sb
->
sv
_fic_size
=
COH_NICINOD
;
sb
->
sv
_flc_size
=
COH_NICFREE
;
sb
->
sv_sbd1
=
(
char
*
)
sbd
;
sb
->
sv_sbd2
=
(
char
*
)
sbd
;
sb
->
sv
_sb_fic_count
=
&
sbd
->
s_ninode
;
sb
->
sv
_sb_fic_inodes
=
&
sbd
->
s_inode
[
0
];
sb
->
sv
_sb_total_free_inodes
=
&
sbd
->
s_tinode
;
sb
->
sv
_bcache_count
=
&
sbd
->
s_nfree
;
sb
->
sv
_bcache
=
&
sbd
->
s_free
[
0
];
sb
->
sv
_free_blocks
=
&
sbd
->
s_tfree
;
sb
->
sv
_sb_time
=
&
sbd
->
s_time
;
sb
->
sv_firstdatazone
=
fs16_to_cpu
(
sb
,
sbd
->
s_isize
);
sb
->
sv_nzones
=
fs32_to_cpu
(
sb
,
sbd
->
s_fsize
);
sb
i
->
s
_link_max
=
COH_LINK_MAX
;
sb
i
->
s
_fic_size
=
COH_NICINOD
;
sb
i
->
s
_flc_size
=
COH_NICFREE
;
sb
i
->
s_sbd1
=
(
char
*
)
sbd
;
sb
i
->
s_sbd2
=
(
char
*
)
sbd
;
sb
i
->
s
_sb_fic_count
=
&
sbd
->
s_ninode
;
sb
i
->
s
_sb_fic_inodes
=
&
sbd
->
s_inode
[
0
];
sb
i
->
s
_sb_total_free_inodes
=
&
sbd
->
s_tinode
;
sb
i
->
s
_bcache_count
=
&
sbd
->
s_nfree
;
sb
i
->
s
_bcache
=
&
sbd
->
s_free
[
0
];
sb
i
->
s
_free_blocks
=
&
sbd
->
s_tfree
;
sb
i
->
s
_sb_time
=
&
sbd
->
s_time
;
sb
i
->
s_firstdatazone
=
fs16_to_cpu
(
sbi
,
sbd
->
s_isize
);
sb
i
->
s_nzones
=
fs32_to_cpu
(
sbi
,
sbd
->
s_fsize
);
}
static
void
detected_v7
(
struct
s
uper_block
*
sb
)
static
void
detected_v7
(
struct
s
ysv_sb_info
*
sbi
)
{
struct
buffer_head
*
bh2
=
sb
->
sv
_bh2
;
struct
buffer_head
*
bh2
=
sb
i
->
s
_bh2
;
struct
v7_super_block
*
sbd
=
(
struct
v7_super_block
*
)
bh2
->
b_data
;
sb
->
sv
_link_max
=
V7_LINK_MAX
;
sb
->
sv
_fic_size
=
V7_NICINOD
;
sb
->
sv
_flc_size
=
V7_NICFREE
;
sb
->
sv
_sbd1
=
(
char
*
)
sbd
;
sb
->
sv
_sbd2
=
(
char
*
)
sbd
;
sb
->
sv
_sb_fic_count
=
&
sbd
->
s_ninode
;
sb
->
sv
_sb_fic_inodes
=
&
sbd
->
s_inode
[
0
];
sb
->
sv
_sb_total_free_inodes
=
&
sbd
->
s_tinode
;
sb
->
sv
_bcache_count
=
&
sbd
->
s_nfree
;
sb
->
sv
_bcache
=
&
sbd
->
s_free
[
0
];
sb
->
sv
_free_blocks
=
&
sbd
->
s_tfree
;
sb
->
sv
_sb_time
=
&
sbd
->
s_time
;
sb
->
sv_firstdatazone
=
fs16_to_cpu
(
sb
,
sbd
->
s_isize
);
sb
->
sv_nzones
=
fs32_to_cpu
(
sb
,
sbd
->
s_fsize
);
sb
i
->
s
_link_max
=
V7_LINK_MAX
;
sb
i
->
s
_fic_size
=
V7_NICINOD
;
sb
i
->
s
_flc_size
=
V7_NICFREE
;
sb
i
->
s
_sbd1
=
(
char
*
)
sbd
;
sb
i
->
s
_sbd2
=
(
char
*
)
sbd
;
sb
i
->
s
_sb_fic_count
=
&
sbd
->
s_ninode
;
sb
i
->
s
_sb_fic_inodes
=
&
sbd
->
s_inode
[
0
];
sb
i
->
s
_sb_total_free_inodes
=
&
sbd
->
s_tinode
;
sb
i
->
s
_bcache_count
=
&
sbd
->
s_nfree
;
sb
i
->
s
_bcache
=
&
sbd
->
s_free
[
0
];
sb
i
->
s
_free_blocks
=
&
sbd
->
s_tfree
;
sb
i
->
s
_sb_time
=
&
sbd
->
s_time
;
sb
i
->
s_firstdatazone
=
fs16_to_cpu
(
sbi
,
sbd
->
s_isize
);
sb
i
->
s_nzones
=
fs32_to_cpu
(
sbi
,
sbd
->
s_fsize
);
}
static
int
detect_xenix
(
struct
super_block
*
sb
,
struct
buffer_head
*
bh
)
static
int
detect_xenix
(
struct
sysv_sb_info
*
sbi
,
struct
buffer_head
*
bh
)
{
struct
xenix_super_block
*
sbd
=
(
struct
xenix_super_block
*
)
bh
->
b_data
;
struct
xenix_super_block
*
sbd
=
(
struct
xenix_super_block
*
)
bh
->
b_data
;
if
(
sbd
->
s_magic
==
cpu_to_le32
(
0x2b5544
))
sb
->
sv
_bytesex
=
BYTESEX_LE
;
sb
i
->
s
_bytesex
=
BYTESEX_LE
;
else
if
(
sbd
->
s_magic
==
cpu_to_be32
(
0x2b5544
))
sb
->
sv
_bytesex
=
BYTESEX_BE
;
sb
i
->
s
_bytesex
=
BYTESEX_BE
;
else
return
0
;
if
(
sbd
->
s_type
>
2
||
sbd
->
s_type
<
1
)
return
0
;
sb
->
sv
_type
=
FSTYPE_XENIX
;
sb
i
->
s
_type
=
FSTYPE_XENIX
;
return
sbd
->
s_type
;
}
static
int
detect_sysv
(
struct
super_block
*
sb
,
struct
buffer_head
*
bh
)
static
int
detect_sysv
(
struct
sysv_sb_info
*
sbi
,
struct
buffer_head
*
bh
)
{
struct
super_block
*
sb
=
sbi
->
s_sb
;
/* All relevant fields are at the same offsets in R2 and R4 */
struct
sysv4_super_block
*
sbd
;
sbd
=
(
struct
sysv4_super_block
*
)
(
bh
->
b_data
+
BLOCK_SIZE
/
2
);
if
(
sbd
->
s_magic
==
cpu_to_le32
(
0xfd187e20
))
sb
->
sv
_bytesex
=
BYTESEX_LE
;
sb
i
->
s
_bytesex
=
BYTESEX_LE
;
else
if
(
sbd
->
s_magic
==
cpu_to_be32
(
0xfd187e20
))
sb
->
sv
_bytesex
=
BYTESEX_BE
;
sb
i
->
s
_bytesex
=
BYTESEX_BE
;
else
return
0
;
if
(
fs16_to_cpu
(
sb
,
sbd
->
s_nfree
)
==
0xffff
)
{
sb
->
sv
_type
=
FSTYPE_AFS
;
if
(
fs16_to_cpu
(
sb
i
,
sbd
->
s_nfree
)
==
0xffff
)
{
sb
i
->
s
_type
=
FSTYPE_AFS
;
if
(
!
(
sb
->
s_flags
&
MS_RDONLY
))
{
printk
(
"SysV FS: SCO EAFS on %s detected, "
"forcing read-only mode.
\n
"
,
...
...
@@ -214,11 +214,11 @@ static int detect_sysv (struct super_block *sb, struct buffer_head *bh)
return
sbd
->
s_type
;
}
if
(
fs32_to_cpu
(
sb
,
sbd
->
s_time
)
<
JAN_1_1980
)
{
if
(
fs32_to_cpu
(
sb
i
,
sbd
->
s_time
)
<
JAN_1_1980
)
{
/* this is likely to happen on SystemV2 FS */
if
(
sbd
->
s_type
>
3
||
sbd
->
s_type
<
1
)
return
0
;
sb
->
sv
_type
=
FSTYPE_SYSV2
;
sb
i
->
s
_type
=
FSTYPE_SYSV2
;
return
sbd
->
s_type
;
}
if
((
sbd
->
s_type
>
3
||
sbd
->
s_type
<
1
)
&&
...
...
@@ -236,11 +236,11 @@ static int detect_sysv (struct super_block *sb, struct buffer_head *bh)
sb
->
s_flags
|=
MS_RDONLY
;
}
sb
->
sv
_type
=
FSTYPE_SYSV4
;
sb
i
->
s
_type
=
FSTYPE_SYSV4
;
return
sbd
->
s_type
>=
0x10
?
(
sbd
->
s_type
>>
4
)
:
sbd
->
s_type
;
}
static
int
detect_coherent
(
struct
super_block
*
sb
,
struct
buffer_head
*
bh
)
static
int
detect_coherent
(
struct
sysv_sb_info
*
sbi
,
struct
buffer_head
*
bh
)
{
struct
coh_super_block
*
sbd
;
...
...
@@ -248,21 +248,21 @@ static int detect_coherent (struct super_block *sb, struct buffer_head *bh)
if
((
memcmp
(
sbd
->
s_fname
,
"noname"
,
6
)
&&
memcmp
(
sbd
->
s_fname
,
"xxxxx "
,
6
))
||
(
memcmp
(
sbd
->
s_fpack
,
"nopack"
,
6
)
&&
memcmp
(
sbd
->
s_fpack
,
"xxxxx
\n
"
,
6
)))
return
0
;
sb
->
sv
_bytesex
=
BYTESEX_PDP
;
sb
->
sv
_type
=
FSTYPE_COH
;
sb
i
->
s
_bytesex
=
BYTESEX_PDP
;
sb
i
->
s
_type
=
FSTYPE_COH
;
return
1
;
}
static
int
detect_sysv_odd
(
struct
s
uper_block
*
sb
,
struct
buffer_head
*
bh
)
static
int
detect_sysv_odd
(
struct
s
ysv_sb_info
*
sbi
,
struct
buffer_head
*
bh
)
{
int
size
=
detect_sysv
(
sb
,
bh
);
int
size
=
detect_sysv
(
sb
i
,
bh
);
return
size
>
2
?
0
:
size
;
}
static
struct
{
int
block
;
int
(
*
test
)(
struct
s
uper_block
*
,
struct
buffer_head
*
);
int
(
*
test
)(
struct
s
ysv_sb_info
*
,
struct
buffer_head
*
);
}
flavours
[]
=
{
{
1
,
detect_xenix
},
{
0
,
detect_sysv
},
...
...
@@ -281,7 +281,7 @@ static char *flavour_names[] = {
[
FSTYPE_AFS
]
"AFS"
,
};
static
void
(
*
flavour_setup
[])(
struct
s
uper_block
*
)
=
{
static
void
(
*
flavour_setup
[])(
struct
s
ysv_sb_info
*
)
=
{
[
FSTYPE_XENIX
]
detected_xenix
,
[
FSTYPE_SYSV4
]
detected_sysv4
,
[
FSTYPE_SYSV2
]
detected_sysv2
,
...
...
@@ -292,34 +292,35 @@ static void (*flavour_setup[])(struct super_block *) = {
static
int
complete_read_super
(
struct
super_block
*
sb
,
int
silent
,
int
size
)
{
struct
sysv_sb_info
*
sbi
=
SYSV_SB
(
sb
);
struct
inode
*
root_inode
;
char
*
found
=
flavour_names
[
sb
->
sv
_type
];
char
*
found
=
flavour_names
[
sb
i
->
s
_type
];
u_char
n_bits
=
size
+
8
;
int
bsize
=
1
<<
n_bits
;
int
bsize_4
=
bsize
>>
2
;
sb
->
sv
_firstinodezone
=
2
;
sb
i
->
s
_firstinodezone
=
2
;
flavour_setup
[
sb
->
sv_type
](
sb
);
flavour_setup
[
sb
i
->
s_type
](
sbi
);
sb
->
sv
_truncate
=
1
;
sb
->
sv_ndatazones
=
sb
->
sv_nzones
-
sb
->
sv
_firstdatazone
;
sb
->
sv
_inodes_per_block
=
bsize
>>
6
;
sb
->
sv
_inodes_per_block_1
=
(
bsize
>>
6
)
-
1
;
sb
->
sv
_inodes_per_block_bits
=
n_bits
-
6
;
sb
->
sv
_ind_per_block
=
bsize_4
;
sb
->
sv
_ind_per_block_2
=
bsize_4
*
bsize_4
;
sb
->
sv
_toobig_block
=
10
+
bsize_4
*
(
1
+
bsize_4
*
(
1
+
bsize_4
));
sb
->
sv
_ind_per_block_bits
=
n_bits
-
2
;
sb
->
sv_ninodes
=
(
sb
->
sv_firstdatazone
-
sb
->
sv
_firstinodezone
)
<<
sb
->
sv
_inodes_per_block_bits
;
sb
i
->
s
_truncate
=
1
;
sb
i
->
s_ndatazones
=
sbi
->
s_nzones
-
sbi
->
s
_firstdatazone
;
sb
i
->
s
_inodes_per_block
=
bsize
>>
6
;
sb
i
->
s
_inodes_per_block_1
=
(
bsize
>>
6
)
-
1
;
sb
i
->
s
_inodes_per_block_bits
=
n_bits
-
6
;
sb
i
->
s
_ind_per_block
=
bsize_4
;
sb
i
->
s
_ind_per_block_2
=
bsize_4
*
bsize_4
;
sb
i
->
s
_toobig_block
=
10
+
bsize_4
*
(
1
+
bsize_4
*
(
1
+
bsize_4
));
sb
i
->
s
_ind_per_block_bits
=
n_bits
-
2
;
sb
i
->
s_ninodes
=
(
sbi
->
s_firstdatazone
-
sbi
->
s
_firstinodezone
)
<<
sb
i
->
s
_inodes_per_block_bits
;
if
(
!
silent
)
printk
(
"VFS: Found a %s FS (block size = %ld) on device %s
\n
"
,
found
,
sb
->
s_blocksize
,
sb
->
s_id
);
sb
->
s_magic
=
SYSV_MAGIC_BASE
+
sb
->
sv
_type
;
sb
->
s_magic
=
SYSV_MAGIC_BASE
+
sb
i
->
s
_type
;
/* set up enough so that it can read an inode */
sb
->
s_op
=
&
sysv_sops
;
root_inode
=
iget
(
sb
,
SYSV_ROOT_INO
);
...
...
@@ -333,7 +334,7 @@ static int complete_read_super(struct super_block *sb, int silent, int size)
printk
(
"SysV FS: get root dentry failed
\n
"
);
return
0
;
}
if
(
sb
->
sv
_truncate
)
if
(
sb
i
->
s
_truncate
)
sb
->
s_root
->
d_op
=
&
sysv_dentry_operations
;
sb
->
s_flags
|=
MS_RDONLY
;
sb
->
s_dirt
=
1
;
...
...
@@ -342,30 +343,39 @@ static int complete_read_super(struct super_block *sb, int silent, int size)
static
int
sysv_fill_super
(
struct
super_block
*
sb
,
void
*
data
,
int
silent
)
{
struct
buffer_head
*
bh1
;
struct
buffer_head
*
bh
=
NULL
;
struct
buffer_head
*
bh1
,
*
bh
=
NULL
;
struct
sysv_sb_info
*
sbi
;
unsigned
long
blocknr
;
int
size
=
0
;
int
i
;
int
size
=
0
,
i
;
if
(
1024
!=
sizeof
(
struct
xenix_super_block
))
panic
(
"Xenix FS: bad super-block size"
);
if
((
512
!=
sizeof
(
struct
sysv4_super_block
))
||
(
512
!=
sizeof
(
struct
sysv2_super_block
)))
panic
(
"SystemV FS: bad super-block size"
);
panic
(
"Xenix FS: bad superblock size"
);
if
(
512
!=
sizeof
(
struct
sysv4_super_block
))
panic
(
"SystemV FS: bad superblock size"
);
if
(
512
!=
sizeof
(
struct
sysv2_super_block
))
panic
(
"SystemV FS: bad superblock size"
);
if
(
500
!=
sizeof
(
struct
coh_super_block
))
panic
(
"Coherent FS: bad super
-
block size"
);
panic
(
"Coherent FS: bad superblock size"
);
if
(
64
!=
sizeof
(
struct
sysv_inode
))
panic
(
"sysv fs: bad i-node size"
);
panic
(
"sysv fs: bad inode size"
);
sbi
=
kmalloc
(
sizeof
(
struct
sysv_sb_info
),
GFP_KERNEL
);
if
(
!
sbi
)
return
-
ENOMEM
;
memset
(
sbi
,
0
,
sizeof
(
struct
sysv_sb_info
));
sbi
->
s_sb
=
sb
;
sbi
->
s_block_base
=
0
;
sb
->
u
.
generic_sbp
=
sbi
;
sb_set_blocksize
(
sb
,
BLOCK_SIZE
);
sb
->
sv_block_base
=
0
;
for
(
i
=
0
;
i
<
sizeof
(
flavours
)
/
sizeof
(
flavours
[
0
])
&&
!
size
;
i
++
)
{
brelse
(
bh
);
bh
=
sb_bread
(
sb
,
flavours
[
i
].
block
);
if
(
!
bh
)
continue
;
size
=
flavours
[
i
].
test
(
sb
,
bh
);
size
=
flavours
[
i
].
test
(
SYSV_SB
(
sb
)
,
bh
);
}
if
(
!
size
)
...
...
@@ -393,8 +403,8 @@ static int sysv_fill_super(struct super_block *sb, void *data, int silent)
}
if
(
bh
&&
bh1
)
{
sb
->
sv
_bh1
=
bh1
;
sb
->
sv
_bh2
=
bh
;
sb
i
->
s
_bh1
=
bh1
;
sb
i
->
s
_bh2
=
bh
;
if
(
complete_read_super
(
sb
,
silent
,
size
))
return
0
;
}
...
...
@@ -404,6 +414,7 @@ static int sysv_fill_super(struct super_block *sb, void *data, int silent)
sb_set_blocksize
(
sb
,
BLOCK_SIZE
);
printk
(
"oldfs: cannot read superblock
\n
"
);
failed:
kfree
(
sbi
);
return
-
EINVAL
;
Eunknown:
...
...
@@ -422,6 +433,7 @@ static int sysv_fill_super(struct super_block *sb, void *data, int silent)
static
int
v7_fill_super
(
struct
super_block
*
sb
,
void
*
data
,
int
silent
)
{
struct
sysv_sb_info
*
sbi
;
struct
buffer_head
*
bh
,
*
bh2
=
NULL
;
struct
v7_super_block
*
v7sb
;
struct
sysv_inode
*
v7i
;
...
...
@@ -431,9 +443,17 @@ static int v7_fill_super(struct super_block *sb, void *data, int silent)
if
(
64
!=
sizeof
(
struct
sysv_inode
))
panic
(
"sysv fs: bad i-node size"
);
sb
->
sv_type
=
FSTYPE_V7
;
sb
->
sv_bytesex
=
BYTESEX_PDP
;
sbi
=
kmalloc
(
sizeof
(
struct
sysv_sb_info
),
GFP_KERNEL
);
if
(
!
sbi
)
return
-
ENOMEM
;
memset
(
sbi
,
0
,
sizeof
(
struct
sysv_sb_info
));
sbi
->
s_sb
=
sb
;
sbi
->
s_block_base
=
0
;
sbi
->
s_type
=
FSTYPE_V7
;
sbi
->
s_bytesex
=
BYTESEX_PDP
;
sb
->
u
.
generic_sbp
=
sbi
;
sb_set_blocksize
(
sb
,
512
);
if
((
bh
=
sb_bread
(
sb
,
1
))
==
NULL
)
{
...
...
@@ -445,9 +465,9 @@ static int v7_fill_super(struct super_block *sb, void *data, int silent)
/* plausibility check on superblock */
v7sb
=
(
struct
v7_super_block
*
)
bh
->
b_data
;
if
(
fs16_to_cpu
(
sb
,
v7sb
->
s_nfree
)
>
V7_NICFREE
||
fs16_to_cpu
(
sb
,
v7sb
->
s_ninode
)
>
V7_NICINOD
||
fs32_to_cpu
(
sb
,
v7sb
->
s_time
)
==
0
)
if
(
fs16_to_cpu
(
sb
i
,
v7sb
->
s_nfree
)
>
V7_NICFREE
||
fs16_to_cpu
(
sb
i
,
v7sb
->
s_ninode
)
>
V7_NICINOD
||
fs32_to_cpu
(
sb
i
,
v7sb
->
s_time
)
==
0
)
goto
failed
;
/* plausibility check on root inode: it is a directory,
...
...
@@ -455,20 +475,21 @@ static int v7_fill_super(struct super_block *sb, void *data, int silent)
if
((
bh2
=
sb_bread
(
sb
,
2
))
==
NULL
)
goto
failed
;
v7i
=
(
struct
sysv_inode
*
)(
bh2
->
b_data
+
64
);
if
((
fs16_to_cpu
(
sb
,
v7i
->
i_mode
)
&
~
0777
)
!=
S_IFDIR
||
(
fs32_to_cpu
(
sb
,
v7i
->
i_size
)
==
0
)
||
(
fs32_to_cpu
(
sb
,
v7i
->
i_size
)
&
017
)
!=
0
)
if
((
fs16_to_cpu
(
sb
i
,
v7i
->
i_mode
)
&
~
0777
)
!=
S_IFDIR
||
(
fs32_to_cpu
(
sb
i
,
v7i
->
i_size
)
==
0
)
||
(
fs32_to_cpu
(
sb
i
,
v7i
->
i_size
)
&
017
)
!=
0
)
goto
failed
;
brelse
(
bh2
);
sb
->
sv
_bh1
=
bh
;
sb
->
sv
_bh2
=
bh
;
sb
i
->
s
_bh1
=
bh
;
sb
i
->
s
_bh2
=
bh
;
if
(
complete_read_super
(
sb
,
silent
,
1
))
return
0
;
failed:
brelse
(
bh2
);
brelse
(
bh
);
kfree
(
sbi
);
return
-
EINVAL
;
}
...
...
fs/sysv/symlink.c
View file @
84f922f1
...
...
@@ -5,8 +5,7 @@
* Aug 2001, Christoph Hellwig (hch@infradead.org)
*/
#include <linux/fs.h>
#include <linux/sysv_fs.h>
#include "sysv.h"
static
int
sysv_readlink
(
struct
dentry
*
dentry
,
char
*
buffer
,
int
buflen
)
{
...
...
include/linux/sysv_fs_sb
.h
→
fs/sysv/sysv
.h
View file @
84f922f1
#ifndef _SYSV_FS_SB
#define _SYSV_FS_SB
#ifndef _SYSV_H
#define _SYSV_H
#include <linux/fs.h>
#include <linux/sysv_fs.h>
/*
* SystemV/V7/Coherent super-block data in memory
*
* The SystemV/V7/Coherent superblock contains dynamic data (it gets modified
* while the system is running). This is in contrast to the Minix and Berkeley
* filesystems (where the superblock is never modified). This affects the
...
...
@@ -11,6 +15,7 @@
*/
struct
sysv_sb_info
{
struct
super_block
*
s_sb
;
/* VFS superblock */
int
s_type
;
/* file system type: FSTYPE_{XENIX|SYSV|COH} */
char
s_bytesex
;
/* bytesex (le/be/pdp) */
char
s_truncate
;
/* if 1: names > SYSV_NAMELEN chars are truncated */
...
...
@@ -50,40 +55,182 @@ struct sysv_sb_info {
u32
s_nzones
;
/* same as s_sbd->s_fsize */
u16
s_namelen
;
/* max length of dir entry */
};
/* The field s_toobig_block is currently unused. */
/* sv_ == u.sysv_sb.s_ */
#define sv_type u.sysv_sb.s_type
#define sv_bytesex u.sysv_sb.s_bytesex
#define sv_truncate u.sysv_sb.s_truncate
#define sv_link_max u.sysv_sb.s_link_max
#define sv_inodes_per_block u.sysv_sb.s_inodes_per_block
#define sv_inodes_per_block_1 u.sysv_sb.s_inodes_per_block_1
#define sv_inodes_per_block_bits u.sysv_sb.s_inodes_per_block_bits
#define sv_ind_per_block u.sysv_sb.s_ind_per_block
#define sv_ind_per_block_bits u.sysv_sb.s_ind_per_block_bits
#define sv_ind_per_block_2 u.sysv_sb.s_ind_per_block_2
#define sv_toobig_block u.sysv_sb.s_toobig_block
#define sv_block_base u.sysv_sb.s_block_base
#define sv_fic_size u.sysv_sb.s_fic_size
#define sv_flc_size u.sysv_sb.s_flc_size
#define sv_bh1 u.sysv_sb.s_bh1
#define sv_bh2 u.sysv_sb.s_bh2
#define sv_sbd1 u.sysv_sb.s_sbd1
#define sv_sbd2 u.sysv_sb.s_sbd2
#define sv_sb_fic_count u.sysv_sb.s_sb_fic_count
#define sv_sb_fic_inodes u.sysv_sb.s_sb_fic_inodes
#define sv_sb_total_free_inodes u.sysv_sb.s_sb_total_free_inodes
#define sv_bcache_count u.sysv_sb.s_bcache_count
#define sv_bcache u.sysv_sb.s_bcache
#define sv_free_blocks u.sysv_sb.s_free_blocks
#define sv_sb_time u.sysv_sb.s_sb_time
#define sv_sb_state u.sysv_sb.s_sb_state
#define sv_firstinodezone u.sysv_sb.s_firstinodezone
#define sv_firstdatazone u.sysv_sb.s_firstdatazone
#define sv_ninodes u.sysv_sb.s_ninodes
#define sv_ndatazones u.sysv_sb.s_ndatazones
#define sv_nzones u.sysv_sb.s_nzones
#define sv_namelen u.sysv_sb.s_namelen
/*
* SystemV/V7/Coherent FS inode data in memory
*/
struct
sysv_inode_info
{
u32
i_data
[
13
];
u32
i_dir_start_lookup
;
struct
inode
vfs_inode
;
};
static
inline
struct
sysv_inode_info
*
SYSV_I
(
struct
inode
*
inode
)
{
return
list_entry
(
inode
,
struct
sysv_inode_info
,
vfs_inode
);
}
static
inline
struct
sysv_sb_info
*
SYSV_SB
(
struct
super_block
*
sb
)
{
return
sb
->
u
.
generic_sbp
;
}
/* identify the FS in memory */
enum
{
FSTYPE_NONE
=
0
,
FSTYPE_XENIX
,
FSTYPE_SYSV4
,
FSTYPE_SYSV2
,
FSTYPE_COH
,
FSTYPE_V7
,
FSTYPE_AFS
,
FSTYPE_END
,
};
#define SYSV_MAGIC_BASE 0x012FF7B3
#define XENIX_SUPER_MAGIC (SYSV_MAGIC_BASE+FSTYPE_XENIX)
#define SYSV4_SUPER_MAGIC (SYSV_MAGIC_BASE+FSTYPE_SYSV4)
#define SYSV2_SUPER_MAGIC (SYSV_MAGIC_BASE+FSTYPE_SYSV2)
#define COH_SUPER_MAGIC (SYSV_MAGIC_BASE+FSTYPE_COH)
/* Admissible values for i_nlink: 0.._LINK_MAX */
enum
{
XENIX_LINK_MAX
=
126
,
/* ?? */
SYSV_LINK_MAX
=
126
,
/* 127? 251? */
V7_LINK_MAX
=
126
,
/* ?? */
COH_LINK_MAX
=
10000
,
};
static
inline
void
dirty_sb
(
struct
super_block
*
sb
)
{
struct
sysv_sb_info
*
sbi
=
SYSV_SB
(
sb
);
mark_buffer_dirty
(
sbi
->
s_bh1
);
if
(
sbi
->
s_bh1
!=
sbi
->
s_bh2
)
mark_buffer_dirty
(
sbi
->
s_bh2
);
sb
->
s_dirt
=
1
;
}
/* ialloc.c */
extern
struct
sysv_inode
*
sysv_raw_inode
(
struct
super_block
*
,
unsigned
,
struct
buffer_head
**
);
extern
struct
inode
*
sysv_new_inode
(
const
struct
inode
*
,
mode_t
);
extern
void
sysv_free_inode
(
struct
inode
*
);
extern
unsigned
long
sysv_count_free_inodes
(
struct
super_block
*
);
/* balloc.c */
extern
u32
sysv_new_block
(
struct
super_block
*
);
extern
void
sysv_free_block
(
struct
super_block
*
,
u32
);
extern
unsigned
long
sysv_count_free_blocks
(
struct
super_block
*
);
/* itree.c */
extern
void
sysv_truncate
(
struct
inode
*
);
/* inode.c */
extern
void
sysv_write_inode
(
struct
inode
*
,
int
);
extern
int
sysv_sync_inode
(
struct
inode
*
);
extern
int
sysv_sync_file
(
struct
file
*
,
struct
dentry
*
,
int
);
extern
void
sysv_set_inode
(
struct
inode
*
,
dev_t
);
/* dir.c */
extern
struct
sysv_dir_entry
*
sysv_find_entry
(
struct
dentry
*
,
struct
page
**
);
extern
int
sysv_add_link
(
struct
dentry
*
,
struct
inode
*
);
extern
int
sysv_delete_entry
(
struct
sysv_dir_entry
*
,
struct
page
*
);
extern
int
sysv_make_empty
(
struct
inode
*
,
struct
inode
*
);
extern
int
sysv_empty_dir
(
struct
inode
*
);
extern
void
sysv_set_link
(
struct
sysv_dir_entry
*
,
struct
page
*
,
struct
inode
*
);
extern
struct
sysv_dir_entry
*
sysv_dotdot
(
struct
inode
*
,
struct
page
**
);
extern
ino_t
sysv_inode_by_name
(
struct
dentry
*
);
extern
struct
inode_operations
sysv_file_inode_operations
;
extern
struct
inode_operations
sysv_dir_inode_operations
;
extern
struct
inode_operations
sysv_fast_symlink_inode_operations
;
extern
struct
file_operations
sysv_file_operations
;
extern
struct
file_operations
sysv_dir_operations
;
extern
struct
address_space_operations
sysv_aops
;
extern
struct
super_operations
sysv_sops
;
extern
struct
dentry_operations
sysv_dentry_operations
;
enum
{
BYTESEX_LE
,
BYTESEX_PDP
,
BYTESEX_BE
,
};
static
inline
u32
PDP_swab
(
u32
x
)
{
#ifdef __LITTLE_ENDIAN
return
((
x
&
0xffff
)
<<
16
)
|
((
x
&
0xffff0000
)
>>
16
);
#else
#ifdef __BIG_ENDIAN
return
((
x
&
0xff00ff
)
<<
8
)
|
((
x
&
0xff00ff00
)
>>
8
);
#else
#error BYTESEX
#endif
#endif
}
static
inline
u32
fs32_to_cpu
(
struct
sysv_sb_info
*
sbi
,
u32
n
)
{
if
(
sbi
->
s_bytesex
==
BYTESEX_PDP
)
return
PDP_swab
(
n
);
else
if
(
sbi
->
s_bytesex
==
BYTESEX_LE
)
return
le32_to_cpu
(
n
);
else
return
be32_to_cpu
(
n
);
}
static
inline
u32
cpu_to_fs32
(
struct
sysv_sb_info
*
sbi
,
u32
n
)
{
if
(
sbi
->
s_bytesex
==
BYTESEX_PDP
)
return
PDP_swab
(
n
);
else
if
(
sbi
->
s_bytesex
==
BYTESEX_LE
)
return
cpu_to_le32
(
n
);
else
return
cpu_to_be32
(
n
);
}
static
inline
u32
fs32_add
(
struct
sysv_sb_info
*
sbi
,
u32
*
n
,
int
d
)
{
if
(
sbi
->
s_bytesex
==
BYTESEX_PDP
)
return
*
n
=
PDP_swab
(
PDP_swab
(
*
n
)
+
d
);
else
if
(
sbi
->
s_bytesex
==
BYTESEX_LE
)
return
*
n
=
cpu_to_le32
(
le32_to_cpu
(
*
n
)
+
d
);
else
return
*
n
=
cpu_to_be32
(
be32_to_cpu
(
*
n
)
+
d
);
}
static
inline
u16
fs16_to_cpu
(
struct
sysv_sb_info
*
sbi
,
u16
n
)
{
if
(
sbi
->
s_bytesex
!=
BYTESEX_BE
)
return
le16_to_cpu
(
n
);
else
return
be16_to_cpu
(
n
);
}
static
inline
u16
cpu_to_fs16
(
struct
sysv_sb_info
*
sbi
,
u16
n
)
{
if
(
sbi
->
s_bytesex
!=
BYTESEX_BE
)
return
cpu_to_le16
(
n
);
else
return
cpu_to_be16
(
n
);
}
static
inline
u16
fs16_add
(
struct
sysv_sb_info
*
sbi
,
u16
*
n
,
int
d
)
{
if
(
sbi
->
s_bytesex
!=
BYTESEX_BE
)
return
*
n
=
cpu_to_le16
(
le16_to_cpu
(
*
n
)
+
d
);
else
return
*
n
=
cpu_to_be16
(
be16_to_cpu
(
*
n
)
+
d
);
}
#endif
/* _SYSV_H */
include/linux/fs.h
View file @
84f922f1
...
...
@@ -679,7 +679,6 @@ struct quota_mount_options
#include <linux/ext3_fs_sb.h>
#include <linux/hpfs_fs_sb.h>
#include <linux/sysv_fs_sb.h>
#include <linux/ufs_fs_sb.h>
#include <linux/romfs_fs_sb.h>
#include <linux/adfs_fs_sb.h>
...
...
@@ -723,7 +722,6 @@ struct super_block {
union
{
struct
ext3_sb_info
ext3_sb
;
struct
hpfs_sb_info
hpfs_sb
;
struct
sysv_sb_info
sysv_sb
;
struct
ufs_sb_info
ufs_sb
;
struct
romfs_sb_info
romfs_sb
;
struct
adfs_sb_info
adfs_sb
;
...
...
include/linux/sysv_fs.h
View file @
84f922f1
#ifndef _LINUX_SYSV_FS_H
#define _LINUX_SYSV_FS_H
/*
* The SystemV/Coherent filesystem constants/structures/macros
*/
/* This code assumes
- sizeof(short) = 2, sizeof(int) = 4, sizeof(long) = 4,
- alignof(short) = 2, alignof(long) = 4.
*/
#ifdef __GNUC__
#define __packed2__ __attribute__ ((packed, aligned(2)))
#if defined(__GNUC__)
# define __packed2__ __attribute__((packed, aligned(2)))
#else
#error I want gcc!
>>
I
want
to
scream
!
<<
#endif
#include <linux/stat.h>
/* declares S_IFLNK etc. */
#include <linux/sched.h>
/* declares wake_up() */
#include <linux/sysv_fs_sb.h>
/* defines the sv_... shortcuts */
/* temporary hack. */
#include <linux/sysv_fs_i.h>
static
inline
struct
sysv_inode_info
*
SYSV_I
(
struct
inode
*
inode
)
{
/* I think list_entry should have a more descriptive name.. --hch */
return
list_entry
(
inode
,
struct
sysv_inode_info
,
vfs_inode
);
}
/* end temporary hack. */
/* Layout on disk */
/* ============== */
static
inline
u32
PDP_swab
(
u32
x
)
{
#ifdef __LITTLE_ENDIAN
return
((
x
&
0xffff
)
<<
16
)
|
((
x
&
0xffff0000
)
>>
16
);
#else
#ifdef __BIG_ENDIAN
return
((
x
&
0xff00ff
)
<<
8
)
|
((
x
&
0xff00ff00
)
>>
8
);
#else
#error BYTESEX
#endif
#endif
}
/* inode numbers are 16 bit */
typedef
u16
sysv_ino_t
;
/* Block numbers are 24 bit, sometimes stored in 32 bit.
On Coherent FS, they are always stored in PDP-11 manner: the least
significant 16 bits come last.
*/
significant 16 bits come last. */
typedef
u32
sysv_zone_t
;
/* Among the blocks ... */
/* Xenix FS, Coherent FS: block 0 is the boot block, block 1 the super-block.
SystemV FS: block 0 contains both the boot sector and the super-block. */
/* The first inode zone is sb->sv_firstinodezone (1 or 2). */
/* Among the inodes ... */
/* 0 is non-existent */
#define SYSV_BADBL_INO 1
/* inode of bad blocks file */
#define SYSV_ROOT_INO 2
/* inode of root directory */
...
...
@@ -101,7 +53,8 @@ struct xenix_super_block {
};
/* SystemV FS comes in two variants:
/*
* SystemV FS comes in two variants:
* sysv2: System V Release 2 (e.g. Microport), structure elements aligned(2).
* sysv4: System V Release 4 (e.g. Consensys), structure elements aligned(4).
*/
...
...
@@ -223,51 +176,21 @@ struct coh_super_block {
};
/* SystemV/Coherent inode data on disk */
struct
sysv_inode
{
u16
i_mode
;
u16
i_nlink
;
u16
i_uid
;
u16
i_gid
;
u32
i_size
;
union
{
/* directories, regular files, ... */
unsigned
char
i_addb
[
3
*
(
10
+
1
+
1
+
1
)
+
1
];
/* zone numbers: max. 10 data blocks,
* then 1 indirection block,
* then 1 double indirection block,
* then 1 triple indirection block.
* Then maybe a "file generation number" ??
*/
/* named pipes on Coherent */
struct
{
char
p_addp
[
30
];
s16
p_pnc
;
s16
p_prx
;
s16
p_pwx
;
}
i_p
;
}
i_a
;
u8
i_data
[
3
*
(
10
+
1
+
1
+
1
)];
u8
i_gen
;
u32
i_atime
;
/* time of last access */
u32
i_mtime
;
/* time of last modification */
u32
i_ctime
;
/* time of creation */
};
/* Admissible values for i_nlink: 0.._LINK_MAX */
enum
{
XENIX_LINK_MAX
=
126
,
/* ?? */
SYSV_LINK_MAX
=
126
,
/* 127? 251? */
V7_LINK_MAX
=
126
,
/* ?? */
COH_LINK_MAX
=
10000
,
};
/* The number of inodes per block is
sb->sv_inodes_per_block = block_size / sizeof(struct sysv_inode) */
/* The number of indirect pointers per block is
sb->sv_ind_per_block = block_size / sizeof(u32) */
/* SystemV/Coherent directory entry on disk */
#define SYSV_NAMELEN 14
/* max size of name in struct sysv_dir_entry */
struct
sysv_dir_entry
{
sysv_ino_t
inode
;
char
name
[
SYSV_NAMELEN
];
/* up to 14 characters, the rest are zeroes */
...
...
@@ -275,137 +198,4 @@ struct sysv_dir_entry {
#define SYSV_DIRSIZE sizeof(struct sysv_dir_entry)
/* size of every directory entry */
/* Operations */
/* ========== */
/* identify the FS in memory */
enum
{
FSTYPE_NONE
=
0
,
FSTYPE_XENIX
,
FSTYPE_SYSV4
,
FSTYPE_SYSV2
,
FSTYPE_COH
,
FSTYPE_V7
,
FSTYPE_AFS
,
FSTYPE_END
,
};
#define SYSV_MAGIC_BASE 0x012FF7B3
#define XENIX_SUPER_MAGIC (SYSV_MAGIC_BASE+FSTYPE_XENIX)
#define SYSV4_SUPER_MAGIC (SYSV_MAGIC_BASE+FSTYPE_SYSV4)
#define SYSV2_SUPER_MAGIC (SYSV_MAGIC_BASE+FSTYPE_SYSV2)
#define COH_SUPER_MAGIC (SYSV_MAGIC_BASE+FSTYPE_COH)
#ifdef __KERNEL__
enum
{
BYTESEX_LE
,
BYTESEX_PDP
,
BYTESEX_BE
,
};
/*
* Function prototypes
*/
extern
struct
inode
*
sysv_new_inode
(
const
struct
inode
*
,
mode_t
);
extern
void
sysv_free_inode
(
struct
inode
*
);
extern
unsigned
long
sysv_count_free_inodes
(
struct
super_block
*
);
extern
u32
sysv_new_block
(
struct
super_block
*
);
extern
void
sysv_free_block
(
struct
super_block
*
,
u32
);
extern
unsigned
long
sysv_count_free_blocks
(
struct
super_block
*
);
extern
void
sysv_truncate
(
struct
inode
*
);
extern
void
sysv_write_inode
(
struct
inode
*
,
int
);
extern
int
sysv_sync_inode
(
struct
inode
*
);
extern
int
sysv_sync_file
(
struct
file
*
,
struct
dentry
*
,
int
);
extern
void
sysv_set_inode
(
struct
inode
*
,
dev_t
);
extern
struct
sysv_dir_entry
*
sysv_find_entry
(
struct
dentry
*
,
struct
page
**
);
extern
int
sysv_add_link
(
struct
dentry
*
,
struct
inode
*
);
extern
int
sysv_delete_entry
(
struct
sysv_dir_entry
*
,
struct
page
*
);
extern
int
sysv_make_empty
(
struct
inode
*
,
struct
inode
*
);
extern
int
sysv_empty_dir
(
struct
inode
*
);
extern
void
sysv_set_link
(
struct
sysv_dir_entry
*
,
struct
page
*
,
struct
inode
*
);
extern
struct
sysv_dir_entry
*
sysv_dotdot
(
struct
inode
*
,
struct
page
**
);
extern
ino_t
sysv_inode_by_name
(
struct
dentry
*
);
extern
struct
inode_operations
sysv_file_inode_operations
;
extern
struct
inode_operations
sysv_dir_inode_operations
;
extern
struct
inode_operations
sysv_fast_symlink_inode_operations
;
extern
struct
file_operations
sysv_file_operations
;
extern
struct
file_operations
sysv_dir_operations
;
extern
struct
address_space_operations
sysv_aops
;
extern
struct
super_operations
sysv_sops
;
extern
struct
dentry_operations
sysv_dentry_operations
;
extern
struct
sysv_inode
*
sysv_raw_inode
(
struct
super_block
*
,
unsigned
,
struct
buffer_head
**
);
static
inline
void
dirty_sb
(
struct
super_block
*
sb
)
{
mark_buffer_dirty
(
sb
->
sv_bh1
);
if
(
sb
->
sv_bh1
!=
sb
->
sv_bh2
)
mark_buffer_dirty
(
sb
->
sv_bh2
);
sb
->
s_dirt
=
1
;
}
static
inline
u32
fs32_to_cpu
(
struct
super_block
*
sb
,
u32
n
)
{
if
(
sb
->
sv_bytesex
==
BYTESEX_PDP
)
return
PDP_swab
(
n
);
else
if
(
sb
->
sv_bytesex
==
BYTESEX_LE
)
return
le32_to_cpu
(
n
);
else
return
be32_to_cpu
(
n
);
}
static
inline
u32
cpu_to_fs32
(
struct
super_block
*
sb
,
u32
n
)
{
if
(
sb
->
sv_bytesex
==
BYTESEX_PDP
)
return
PDP_swab
(
n
);
else
if
(
sb
->
sv_bytesex
==
BYTESEX_LE
)
return
cpu_to_le32
(
n
);
else
return
cpu_to_be32
(
n
);
}
static
inline
u32
fs32_add
(
struct
super_block
*
sb
,
u32
*
n
,
int
d
)
{
if
(
sb
->
sv_bytesex
==
BYTESEX_PDP
)
return
*
n
=
PDP_swab
(
PDP_swab
(
*
n
)
+
d
);
else
if
(
sb
->
sv_bytesex
==
BYTESEX_LE
)
return
*
n
=
cpu_to_le32
(
le32_to_cpu
(
*
n
)
+
d
);
else
return
*
n
=
cpu_to_be32
(
be32_to_cpu
(
*
n
)
+
d
);
}
static
inline
u16
fs16_to_cpu
(
struct
super_block
*
sb
,
u16
n
)
{
if
(
sb
->
sv_bytesex
!=
BYTESEX_BE
)
return
le16_to_cpu
(
n
);
else
return
be16_to_cpu
(
n
);
}
static
inline
u16
cpu_to_fs16
(
struct
super_block
*
sb
,
u16
n
)
{
if
(
sb
->
sv_bytesex
!=
BYTESEX_BE
)
return
cpu_to_le16
(
n
);
else
return
cpu_to_be16
(
n
);
}
static
inline
u16
fs16_add
(
struct
super_block
*
sb
,
u16
*
n
,
int
d
)
{
if
(
sb
->
sv_bytesex
!=
BYTESEX_BE
)
return
*
n
=
cpu_to_le16
(
le16_to_cpu
(
*
n
)
+
d
);
else
return
*
n
=
cpu_to_be16
(
be16_to_cpu
(
*
n
)
+
d
);
}
#endif
/* __KERNEL__ */
#endif
#endif
/* _LINUX_SYSV_FS_H */
include/linux/sysv_fs_i.h
deleted
100644 → 0
View file @
e66d5915
#ifndef _SYSV_FS_I
#define _SYSV_FS_I
/*
* SystemV/V7/Coherent FS inode data in memory
*/
struct
sysv_inode_info
{
u32
i_data
[
10
+
1
+
1
+
1
];
/* zone numbers: max. 10 data blocks,
* then 1 indirection block,
* then 1 double indirection block,
* then 1 triple indirection block.
*/
u32
i_dir_start_lookup
;
struct
inode
vfs_inode
;
};
#endif
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