Upload
anh-tuan
View
94
Download
5
Embed Size (px)
Citation preview
Systems ProgrammingUser-Space File System
H. Turgut Uyar Sima Uyar
2009
1 / 21
Topics
User-Space Development
FUSEIntroductionRead-Only FilesystemHello, world
2 / 21
System Programming Levels
I compiling the kernel:best performance, every possible functionalityrisky, time-consuming
I kernel modules:very good performance, less risky, fast developmentcan not do everything
I user-space:even less risky, fast development, can use external librariespoorer performance, can not do everything
3 / 21
FUSE
I Filesystem in Userspace
I develop a file system in user space on top of a kernel module
I non-native filesystems (NTFS, ZFS, ...)I changing data storage (SQL, ...)I providing transparent functionality (compression,
encryption, ...)
I two paths for every file/directory:FUSE path - underlying filesystem path
4 / 21
FUSE Structure
5 / 21
FUSE Development
I similar to device driver development:implement system calls
I needed package: libfuse-devI system calls:
I file related:open, release, read, write, getattr, unlink, ...
I directory related:readdir, mkdir, rmdir, ...
6 / 21
FUSE Development
Example (fuse operations)
s t ruc t f u s e o p e r a t i o n s r o f s o p e r = {. g e t a t t r = r o f s g e t a t t r ,. r e a d d i r = r o f s r e a d d i r ,. mkdir = r o f s m k d i r ,. u n l i n k = r o f s u n l i n k ,. r m d i r = r o f s r m d i r ,. rename = r o f s r e n a m e ,. open = r o f s o p e n ,. r e a d = r o f s r e a d ,. w r i t e = r o f s w r i t e ,. r e l e a s e = r o f s r e l e a s e ,. . .
} ;
7 / 21
FUSE Development
Example (path translation)
char ∗ rPath = m a l l o c ( s i z eo f ( char )∗( s t r l e n ( path ) + s t r l e n ( rw path ) + 1 ) ) ;
s t r c p y ( rPath , rw path ) ;i f ( rPath [ s t r l e n ( rPath )−1] == ’ / ’ ) {
rPath [ s t r l e n ( rPath )−1] = ’ \0 ’ ;}s t r c a t ( rPath , path ) ;
return rPath ;
8 / 21
FUSE Development
directory listing: readdir
s t a t i c i n t r o f s r e a d d i r (const char ∗path ,void ∗buf ,f u s e f i l l d i r t f i l l e r ,o f f t o f f s e t ,s t ruc t f u s e f i l e i n f o ∗ f i
) ;
9 / 21
FUSE Development
Example (directory listing)
upath = t r a n s l a t e p a t h ( path ) ;dp = o p e n d i r ( upath ) ; /∗ DIR ∗dp ; ∗/f r e e ( upath ) ;i f ( dp == NULL) {
r e s = −e r r n o ;return r e s ;
}
/∗ f i l l i n the d i r e c t o r y i n f o ∗/
c l o s e d i r ( dp ) ;
10 / 21
FUSE Development
Example (directory info)
/∗ s t r u c t d i r e n t ∗de ; ∗/whi le ( ( de = r e a d d i r ( dp ) ) != NULL) {
s t ruc t s t a t s t ;memset(& st , 0 , s i z eo f ( s t ) ) ;s t . s t i n o = de−>d i n o ;s t . st mode = de−>d t y p e << 1 2 ;i f ( f i l l e r ( buf , de−>d name , &st , 0 ) )
break ;}
11 / 21
FUSE Development
reading file attributes
s t a t i c i n t r o f s g e t a t t r (const char ∗path ,s t ruc t s t a t ∗ s t d a t a
) ;
12 / 21
FUSE Development
Example (reading file attributes)
upath = t r a n s l a t e p a t h ( path ) ;r e s = l s t a t ( upath , s t d a t a ) ;f r e e ( upath ) ;i f ( r e s == −1) {
return −e r r n o ;}
13 / 21
FUSE Development
reading from a file
s t a t i c i n t r o f s r e a d (const char ∗path ,char ∗buf ,s i z e t s i z e ,o f f t o f f s e t ,s t ruc t f u s e f i l e i n f o ∗ f i n f o
) ;
14 / 21
FUSE Development
Example (reading from a file)
upath = t r a n s l a t e p a t h ( path ) ;f d = open ( upath , O RDONLY ) ;f r e e ( upath ) ;i f ( f d == −1) {
r e s = −e r r n o ;return r e s ;
}r e s = pread ( fd , buf , s i z e , o f f s e t ) ;i f ( r e s == −1) {
r e s = −e r r n o ;}c l o s e ( f d ) ;
15 / 21
FUSE Development
modification operations
s t a t i c i n t r o f s m k d i r (const char ∗path ,mode t mode
) ;
s t a t i c i n t r o f s u n l i n k ( const char ∗ path ) ;
/∗ body ∗/return −EROFS ;
16 / 21
FUSE Development
I compiling:gcc −o rofs −Wall −ansi −W −std=c99 −g −ggdb−D GNU SOURCE −D FILE OFFSET BITS=64−lfuse rofs .c
I mounting:./ rofs <rw dir> <ro dir>
I unmounting:fusermount −u <ro dir>
I running in debug mode:./ rofs −d <rw dir> <ro dir>
17 / 21
FUSE Development
Example (fuse operations)
s t a t i c s t ruc t f u s e o p e r a t i o n s h e l l o o p e r = {. g e t a t t r = h e l l o g e t a t t r ,. r e a d d i r = h e l l o r e a d d i r ,. open = h e l l o o p e n ,. r e a d = h e l l o r e a d ,
} ;
18 / 21
FUSE Development
Example (hello readdir)
i f ( st rcmp ( path , ”/ ”) != 0)return −ENOENT;
f i l l e r ( buf , ” . ” , NULL , 0 ) ;f i l l e r ( buf , ” . . ” , NULL , 0 ) ;f i l l e r ( buf , h e l l o p a t h + 1 , NULL , 0 ) ;
19 / 21
FUSE Development
Example (hello getattr)
memset ( s t b u f , 0 , s i z eo f ( s t ruc t s t a t ) ) ;i f ( st rcmp ( path , ”/ ”) == 0) {
s t b u f−>st mode = S IFDIR | 0 7 5 5 ;s t b u f−>s t n l i n k = 2 ;
}e l s e i f ( st rcmp ( path , h e l l o p a t h ) == 0) {
s t b u f−>st mode = S IFREG | 0 4 4 4 ;s t b u f−>s t n l i n k = 1 ;s t b u f−>s t s i z e = s t r l e n ( h e l l o s t r ) ;
}e l s e
r e s = −ENOENT;
20 / 21
FUSE Development
Example (hello read)
i f ( st rcmp ( path , ”/ h e l l o ”) != 0)return −ENOENT;
l e n = s t r l e n ( ”H e l l o , w o r ld !\ n ” ) ;i f ( o f f s e t < l e n ) {
i f ( o f f s e t + s i z e > l e n )s i z e = l e n − o f f s e t ;
memcpy ( buf , ”H e l l o , w o r ld !\ n ”+o f f s e t , s i z e ) ;} e l s e
s i z e = 0 ;
return s i z e ;
21 / 21