Title: Sistema de ficheros ext2
1 Sistema de ficheros ext2
Llamadas al sistema read y write
- Ramírez Viera, Jesús Alberto
- Romero Santana, Samuel
2Llamada al sistema read Uso y parámetros
- La llamada al sistema read realiza la lectura de
datos desde un archivo - Sus parámetros son
- Descriptor del fichero que se va a leer
- Buffer donde se almacenarán los datos
- Número de bytes a leer
- Devuelve
- Número de bytes que se consiguieron leer
- lt 0 en caso de error
3Esquema de funcionamiento del read
Sys_Read
4Llamada al sistema read fs/read_write.c
asmlinkage ssize_t sys_read(unsigned int fd, char
buf, size_t count) ssize_t ret struct file
file ssize_t (read)(struct file , char ,
size_t, loff_t ) lock_kernel() ret
-EBADF file fget(fd) if (!file) goto
bad_file if (!(file-gtf_mode
FMODE_READ)) goto out
5Llamada al sistema read fs/read_write.c
ret locks_verify_area(FLOCK_VERIFY_READ,
file-gtf_dentry-gtd_inode,file, file-gtf_pos,
count) if (ret) goto out ret
-EINVAL if (!file-gtf_op !(read
.file-gtf_op-gtread)) goto out ret read(file,
buf, count, file-gtf_pos) out fput(file)
bad_file unlock_kernel() return ret
6fget fcheckinclude/linux/file.h
extern inline struct file fget(unsigned int
fd) struct file file fcheck(fd)
if (file) file-gtf_count
return file extern inline struct file
fcheck(unsigned int fd) struct file
file NULL if (fd lt current-gtfiles-gtmax
_fds) file current-gtfiles-gtfdfd
return file
7fput include/linux/file.h
void fput(struct file file) int count
file-gtf_count-1 if (!count)
locks_remove_flock(file)
__fput(file) file-gtf_count 0
remove_filp(file)
insert_file_free(file) else
file-gtf_count count
8locks_verify_area include/linux/fs.h
extern inline int locks_verify_area(int
read_write, struct inode inode, struct file
filp, loff_t offset, size_t count) if
(IS_MANDLOCK(inode) (inode-gti_mode (S_ISGID
S_IXGRP)) S_ISGID) return
(locks_mandatory_area(read_write, inode, filp,
offset, count)) return (0)
9locks_mandatory_area include/linux/fs.h
int locks_mandatory_area(int read_write, struct
inode inode,struct file filp, loff_t
offset,size_t count) struct file_lock
fl struct file_lock tfl
memset(tfl, 0, sizeof(tfl)) tfl.fl_file
filp tfl.fl_flags FL_POSIX
FL_ACCESS tfl.fl_owner
current-gtfiles tfl.fl_pid
current-gtpid tfl.fl_type (read_write
FLOCK_VERIFY_WRITE) ? F_WRLCK F_RDLCK
tfl.fl_start offset tfl.fl_end
offset count - 1
10Locks_mandatory_area include/linux/fs.h
repeat for (fl inode-gti_flock fl ! NULL
fl fl-gtfl_next) if
(!(fl-gtfl_flags FL_POSIX))
continue if
(posix_locks_conflict(fl, tfl)) ...
locks_insert_block(fl, tfl)
interruptible_sleep_on(tfl.fl_wait)
locks_delete_block(fl, tfl) ...
Si existe conflicto del tipo escritura contra
bloqueo de lectura o lectura/escritura contra
bloqueo de escritura,ponemos nuestro inodo en
espera, y esperamos por que las condiciones de
bloqueo desaparezcan
11Estructuras include/linux/fs.h
struct file ... struct file_operations
fop ... struct file_operations loff_t
(llseek) (struct file , loff_t, int) ssize_t
(read) (struct file , char , size_t, loff_t
) ssize_t (write) (struct file , const char
, size_t, loff_t ) int (readdir) (struct
file , void , filldir_t) ... static struct
file_operations ext2_file_operations //
include/linux/file.c ext2_file_lseek, / lseek
/ generic_file_read, / read / ext2_file_write
, / write / ...
12Esquema Readpara el formato EXT2
generic_file_read
13generic_file_read/mm/filemap.c
ssize_t generic_file_read(struct file filp,
char buf, size_t count, loff_t ppos)
ssize_t retval retval
-EFAULT if (access_ok(VERIFY_WRITE, buf,
count)) retval 0 if (count)
read_descriptor_t desc
desc.written 0 desc.count count
desc.buf buf desc.error 0
do_generic_file_read(filp, ppos, desc,
file_read_actor) retval desc.written if
(!retval) retval desc.error return
retval
14do_generic_file_read mm/filemap.c
static void do_generic_file_read(struct file
filp, loff_t ppos, read_descriptor_t desc,
read_actor_t actor) ... for () struct
page page, hash if (pos gt
inode-gti_size) break hash
page_hash(inode, pos PAGE_CACHE_MASK) page
__find_page(inode, pos PAGE_CACHE_MASK,
hash) ...
Efectúa un bucle llamando a find_page, para
buscar las páginas correspondientes a los datos a
leer. Se busca en caché.
15do_generic_file_read mm/filemap.c
no_cached_page if (!page_cache)
page_cache page_cache_alloc() if
(page_cache) continue desc-gterror
-ENOMEM break page page_cache_entry(page
_cache) page_cache 0 add_to_page_cache(pag
e, inode, pos PAGE_CACHE_MASK, hash) if
(reada_ok filp-gtf_ramax gt MIN_READAHEAD) fil
p-gtf_ramax MIN_READAHEAD int error
inode-gti_op-gtreadpage(filp, page) if
(!error) goto found_page desc-gterror
error page_cache_release(page) break
16generic_readpage fs/buffer.c
int generic_readpage(struct file file, struct
page page) atomic_inc(page-gtcount)
i PAGE_SIZE gtgt inode-gti_sb-gts_blocksize_
bits block page-gtoffset gtgt
inode-gti_sb-gts_blocksize_bits p nr
do p inode-gti_op-gtbmap(i
node, block) i--
block p while (i
gt 0) ... return 0
17Estructuras de inodos mm/filemap.c
struct dentry unsigned long d_time / used
by d_revalidate / struct dentry_operations
d_op struct super_block d_sb / The root of
the dentry tree / ... struct
inode_operations struct dentry
(follow_link) (struct dentry , struct dentry ,
unsigned int) int (readpage) (struct file ,
struct page ) int (writepage) (struct file ,
struct page ) .... struct inode_operations
ext2_file_inode_operations generic_readpage,
/ readpage / ext2_bmap, / bmap
/ ext2_truncate, / truncate / ext2_permission
, / permission / NULL / smap / ...
18Llamada al sistema write Uso y parámetros
- Sus parámetros son
- Descriptor del fichero que se va a escribir
- Buffer donde están los datos a escribir
- Número de bytes a escribir
- Devuelve
- Número de bytes que se consiguieron escribir
- lt 0 en caso de error
- La llamada al sistema write realiza la escritura
de datos desde un archivo
19sys_write /fs/red_write.c
asmlinkage ssize_t sys_write(unsigned int fd,
const char buf, size_t count) ssize_t
ret struct file file struct inode
inode ssize_t (write)(struct file , const
char , size_t, loff_t ) lock_kernel() ret
-EBADF file fget(fd) if (!file) goto
bad_file if (!(file-gtf_mode
FMODE_WRITE)) goto out
20sys_write/fs/red_write.c
inode file-gtf_dentry-gtd_inode ret
locks_verify_area(FLOCK_VERIFY_WRITE, inode,
file,file-gtf_pos, count) if (ret) goto
out ret -EINVAL if (!file-gtf_op !(write
file-gtf_op-gtwrite)) goto out down(inode-gti_sem
) ret write(file, buf, count,
file-gtf_pos) up(inode-gti_sem) out fput(file)
bad_file unlock_kernel() return ret
21Ext2_file_write fs/ext2/file.c
static ssize_t ext2_file_write (struct file
filp, const char buf, size_t count, loff_t
ppos) ... if (!count) return 0 if
(((signed) count) lt 0) return
-EINVAL write_error buffercount 0 if
(!inode) printk("ext2_file_write inode
NULL\n") return -EINVAL sb
inode-gti_sb if (sb-gts_flags MS_RDONLY)
return -ENOSPC
22Ext2_file_write fs/ext2/file.c
if (!S_ISREG(inode-gti_mode)) ext2_warning
(sb, "ext2_file_write", "mode 07o",
inode-gti_mode) return -EINVAL remove_suid
(inode) if (filp-gtf_flags O_APPEND) pos
inode-gti_size else pos ppos
if (pos ! ppos) return -EINVAL
23Ext2_file_writefs/ext2/file.c
if (((unsigned) pos) gt 0x7FFFFFFFUL) return
-EFBIG if (((unsigned) pos count) gt
0x7FFFFFFFUL) count 0x7FFFFFFFL -
pos if (((signed) count) lt 0) return
-EFBIG ... Se chequean el resto de
parámetros ...
24ext2_file_write fs/ext2/file.c
Bucle de escritura mientras queden datos por
escribir
do bh ext2_getblk (inode, block, 1, err)
if (!bh) if (!written) written
err break if (c gt count) c
count set_bit(BH_Lock, bh-gtb_state) c -
copy_from_user (bh-gtb_data offset, buf,
c) if (c ! sb-gts_blocksize) c
0 unlock_buffer(bh) brelse(bh) if
(!written)written -EFAULT mark_buffer_uptod
ate(bh, 1) unlock_buffer(bh)
25ext2_file_write fs/ext2/file.c
mark_buffer_dirty(bh, 0) ... pos
c written c buf c count -
c ... block offset 0 c
sb-gts_blocksize while (count)
26ext2_file_write fs/ext2/file.c
if (pos gt inode-gti_size) inode-gti_size
pos inode-gti_ctime inode-gti_mtime
CURRENT_TIME ppos pos mark_inode_dirty(ino
de) return written