Loading fs/ubifs/file.c +30 −32 Original line number Diff line number Diff line Loading @@ -21,34 +21,32 @@ */ /* * This file implements VFS file and inode operations of regular files, device * This file implements VFS file and inode operations for regular files, device * nodes and symlinks as well as address space operations. * * UBIFS uses 2 page flags: PG_private and PG_checked. PG_private is set if the * page is dirty and is used for budgeting purposes - dirty pages should not be * budgeted. The PG_checked flag is set if full budgeting is required for the * page e.g., when it corresponds to a file hole or it is just beyond the file * size. The budgeting is done in 'ubifs_write_begin()', because it is OK to * fail in this function, and the budget is released in 'ubifs_write_end()'. So * the PG_private and PG_checked flags carry the information about how the page * was budgeted, to make it possible to release the budget properly. * UBIFS uses 2 page flags: @PG_private and @PG_checked. @PG_private is set if * the page is dirty and is used for optimization purposes - dirty pages are * not budgeted so the flag shows that 'ubifs_write_end()' should not release * the budget for this page. The @PG_checked flag is set if full budgeting is * required for the page e.g., when it corresponds to a file hole or it is * beyond the file size. The budgeting is done in 'ubifs_write_begin()', because * it is OK to fail in this function, and the budget is released in * 'ubifs_write_end()'. So the @PG_private and @PG_checked flags carry * information about how the page was budgeted, to make it possible to release * the budget properly. * * A thing to keep in mind: inode's 'i_mutex' is locked in most VFS operations * we implement. However, this is not true for '->writepage()', which might be * called with 'i_mutex' unlocked. For example, when pdflush is performing * write-back, it calls 'writepage()' with unlocked 'i_mutex', although the * inode has 'I_LOCK' flag in this case. At "normal" work-paths 'i_mutex' is * locked in '->writepage', e.g. in "sys_write -> alloc_pages -> direct reclaim * path'. So, in '->writepage()' we are only guaranteed that the page is * locked. * A thing to keep in mind: inode @i_mutex is locked in most VFS operations we * implement. However, this is not true for 'ubifs_writepage()', which may be * called with @i_mutex unlocked. For example, when pdflush is doing background * write-back, it calls 'ubifs_writepage()' with unlocked @i_mutex. At "normal" * work-paths the @i_mutex is locked in 'ubifs_writepage()', e.g. in the * "sys_write -> alloc_pages -> direct reclaim path". So, in 'ubifs_writepage()' * we are only guaranteed that the page is locked. * * Similarly, 'i_mutex' does not have to be locked in readpage(), e.g., * readahead path does not have it locked ("sys_read -> generic_file_aio_read * -> ondemand_readahead -> readpage"). In case of readahead, 'I_LOCK' flag is * not set as well. However, UBIFS disables readahead. * * This, for example means that there might be 2 concurrent '->writepage()' * calls for the same inode, but different inode dirty pages. * Similarly, @i_mutex is not always locked in 'ubifs_readpage()', e.g., the * read-ahead path does not lock it ("sys_read -> generic_file_aio_read -> * ondemand_readahead -> readpage"). In case of readahead, @I_LOCK flag is not * set as well. However, UBIFS disables readahead. */ #include "ubifs.h" Loading Loading @@ -449,9 +447,9 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping, /* * We change whole page so no need to load it. But we * have to set the @PG_checked flag to make the further * code the page is new. This might be not true, but it * is better to budget more that to read the page from * the media. * code know that the page is new. This might be not * true, but it is better to budget more than to read * the page from the media. */ SetPageChecked(page); skipped_read = 1; Loading Loading @@ -497,8 +495,8 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping, } /* * Whee, we aquired budgeting quickly - without involving * garbage-collection, committing or forceing write-back. We return * Whee, we acquired budgeting quickly - without involving * garbage-collection, committing or forcing write-back. We return * with @ui->ui_mutex locked if we are appending pages, and unlocked * otherwise. This is an optimization (slightly hacky though). */ Loading Loading @@ -562,7 +560,7 @@ static int ubifs_write_end(struct file *file, struct address_space *mapping, /* * Return 0 to force VFS to repeat the whole operation, or the * error code if 'do_readpage()' failes. * error code if 'do_readpage()' fails. */ copied = do_readpage(page); goto out; Loading Loading @@ -1175,11 +1173,11 @@ static int do_truncation(struct ubifs_info *c, struct inode *inode, ui->ui_size = inode->i_size; /* Truncation changes inode [mc]time */ inode->i_mtime = inode->i_ctime = ubifs_current_time(inode); /* The other attributes may be changed at the same time as well */ /* Other attributes may be changed at the same time as well */ do_attr_changes(inode, attr); err = ubifs_jnl_truncate(c, inode, old_size, new_size); mutex_unlock(&ui->ui_mutex); out_budg: if (budgeted) ubifs_release_budget(c, &req); Loading Loading
fs/ubifs/file.c +30 −32 Original line number Diff line number Diff line Loading @@ -21,34 +21,32 @@ */ /* * This file implements VFS file and inode operations of regular files, device * This file implements VFS file and inode operations for regular files, device * nodes and symlinks as well as address space operations. * * UBIFS uses 2 page flags: PG_private and PG_checked. PG_private is set if the * page is dirty and is used for budgeting purposes - dirty pages should not be * budgeted. The PG_checked flag is set if full budgeting is required for the * page e.g., when it corresponds to a file hole or it is just beyond the file * size. The budgeting is done in 'ubifs_write_begin()', because it is OK to * fail in this function, and the budget is released in 'ubifs_write_end()'. So * the PG_private and PG_checked flags carry the information about how the page * was budgeted, to make it possible to release the budget properly. * UBIFS uses 2 page flags: @PG_private and @PG_checked. @PG_private is set if * the page is dirty and is used for optimization purposes - dirty pages are * not budgeted so the flag shows that 'ubifs_write_end()' should not release * the budget for this page. The @PG_checked flag is set if full budgeting is * required for the page e.g., when it corresponds to a file hole or it is * beyond the file size. The budgeting is done in 'ubifs_write_begin()', because * it is OK to fail in this function, and the budget is released in * 'ubifs_write_end()'. So the @PG_private and @PG_checked flags carry * information about how the page was budgeted, to make it possible to release * the budget properly. * * A thing to keep in mind: inode's 'i_mutex' is locked in most VFS operations * we implement. However, this is not true for '->writepage()', which might be * called with 'i_mutex' unlocked. For example, when pdflush is performing * write-back, it calls 'writepage()' with unlocked 'i_mutex', although the * inode has 'I_LOCK' flag in this case. At "normal" work-paths 'i_mutex' is * locked in '->writepage', e.g. in "sys_write -> alloc_pages -> direct reclaim * path'. So, in '->writepage()' we are only guaranteed that the page is * locked. * A thing to keep in mind: inode @i_mutex is locked in most VFS operations we * implement. However, this is not true for 'ubifs_writepage()', which may be * called with @i_mutex unlocked. For example, when pdflush is doing background * write-back, it calls 'ubifs_writepage()' with unlocked @i_mutex. At "normal" * work-paths the @i_mutex is locked in 'ubifs_writepage()', e.g. in the * "sys_write -> alloc_pages -> direct reclaim path". So, in 'ubifs_writepage()' * we are only guaranteed that the page is locked. * * Similarly, 'i_mutex' does not have to be locked in readpage(), e.g., * readahead path does not have it locked ("sys_read -> generic_file_aio_read * -> ondemand_readahead -> readpage"). In case of readahead, 'I_LOCK' flag is * not set as well. However, UBIFS disables readahead. * * This, for example means that there might be 2 concurrent '->writepage()' * calls for the same inode, but different inode dirty pages. * Similarly, @i_mutex is not always locked in 'ubifs_readpage()', e.g., the * read-ahead path does not lock it ("sys_read -> generic_file_aio_read -> * ondemand_readahead -> readpage"). In case of readahead, @I_LOCK flag is not * set as well. However, UBIFS disables readahead. */ #include "ubifs.h" Loading Loading @@ -449,9 +447,9 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping, /* * We change whole page so no need to load it. But we * have to set the @PG_checked flag to make the further * code the page is new. This might be not true, but it * is better to budget more that to read the page from * the media. * code know that the page is new. This might be not * true, but it is better to budget more than to read * the page from the media. */ SetPageChecked(page); skipped_read = 1; Loading Loading @@ -497,8 +495,8 @@ static int ubifs_write_begin(struct file *file, struct address_space *mapping, } /* * Whee, we aquired budgeting quickly - without involving * garbage-collection, committing or forceing write-back. We return * Whee, we acquired budgeting quickly - without involving * garbage-collection, committing or forcing write-back. We return * with @ui->ui_mutex locked if we are appending pages, and unlocked * otherwise. This is an optimization (slightly hacky though). */ Loading Loading @@ -562,7 +560,7 @@ static int ubifs_write_end(struct file *file, struct address_space *mapping, /* * Return 0 to force VFS to repeat the whole operation, or the * error code if 'do_readpage()' failes. * error code if 'do_readpage()' fails. */ copied = do_readpage(page); goto out; Loading Loading @@ -1175,11 +1173,11 @@ static int do_truncation(struct ubifs_info *c, struct inode *inode, ui->ui_size = inode->i_size; /* Truncation changes inode [mc]time */ inode->i_mtime = inode->i_ctime = ubifs_current_time(inode); /* The other attributes may be changed at the same time as well */ /* Other attributes may be changed at the same time as well */ do_attr_changes(inode, attr); err = ubifs_jnl_truncate(c, inode, old_size, new_size); mutex_unlock(&ui->ui_mutex); out_budg: if (budgeted) ubifs_release_budget(c, &req); Loading