X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=fs%2Fudf%2Ffile.c;h=7c7a1b39d56c9071cd28370f92b1945e659aa702;hb=3ad90ec0908e453ba89947fcf7b5f6821b6c1e0c;hp=df070bee8d4f83f3a6966c6fe2485541e217accc;hpb=5ffc4ef45b3b0a57872f631b4e4ceb8ace0d7496;p=safe%2Fjmp%2Flinux-2.6 diff --git a/fs/udf/file.c b/fs/udf/file.c index df070be..7c7a1b3 100644 --- a/fs/udf/file.c +++ b/fs/udf/file.c @@ -41,7 +41,7 @@ #include "udf_i.h" #include "udf_sb.h" -static int udf_adinicb_readpage(struct file *file, struct page * page) +static int udf_adinicb_readpage(struct file *file, struct page *page) { struct inode *inode = page->mapping->host; char *kaddr; @@ -55,6 +55,7 @@ static int udf_adinicb_readpage(struct file *file, struct page * page) SetPageUptodate(page); kunmap(page); unlock_page(page); + return 0; } @@ -71,41 +72,37 @@ static int udf_adinicb_writepage(struct page *page, struct writeback_control *wb SetPageUptodate(page); kunmap(page); unlock_page(page); - return 0; -} -static int udf_adinicb_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to) -{ - kmap(page); return 0; } -static int udf_adinicb_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to) +static int udf_adinicb_write_end(struct file *file, + struct address_space *mapping, + loff_t pos, unsigned len, unsigned copied, + struct page *page, void *fsdata) { - struct inode *inode = page->mapping->host; - char *kaddr = page_address(page); + struct inode *inode = mapping->host; + unsigned offset = pos & (PAGE_CACHE_SIZE - 1); + char *kaddr; + kaddr = kmap_atomic(page, KM_USER0); memcpy(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode) + offset, - kaddr + offset, to - offset); - mark_inode_dirty(inode); - SetPageUptodate(page); - kunmap(page); - /* only one page here */ - if (to > inode->i_size) - inode->i_size = to; - return 0; + kaddr + offset, copied); + kunmap_atomic(kaddr, KM_USER0); + + return simple_write_end(file, mapping, pos, len, copied, page, fsdata); } const struct address_space_operations udf_adinicb_aops = { - .readpage = udf_adinicb_readpage, - .writepage = udf_adinicb_writepage, - .sync_page = block_sync_page, - .prepare_write = udf_adinicb_prepare_write, - .commit_write = udf_adinicb_commit_write, + .readpage = udf_adinicb_readpage, + .writepage = udf_adinicb_writepage, + .sync_page = block_sync_page, + .write_begin = simple_write_begin, + .write_end = udf_adinicb_write_end, }; static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, - unsigned long nr_segs, loff_t ppos) + unsigned long nr_segs, loff_t ppos) { ssize_t retval; struct file *file = iocb->ki_filp; @@ -113,25 +110,20 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, int err, pos; size_t count = iocb->ki_left; - if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) - { + if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) { if (file->f_flags & O_APPEND) pos = inode->i_size; else pos = ppos; if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) + - pos + count)) - { + pos + count)) { udf_expand_file_adinicb(inode, pos + count, &err); - if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) - { + if (UDF_I_ALLOCTYPE(inode) == ICBTAG_FLAG_AD_IN_ICB) { udf_debug("udf_expand_adinicb: err=%d\n", err); return err; } - } - else - { + } else { if (pos + count > inode->i_size) UDF_I_LENALLOC(inode) = pos + count; else @@ -140,9 +132,9 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, } retval = generic_file_aio_write(iocb, iov, nr_segs, ppos); - if (retval > 0) mark_inode_dirty(inode); + return retval; } @@ -181,48 +173,42 @@ static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, * Written, tested, and released. */ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, - unsigned long arg) + unsigned long arg) { + long old_block, new_block; int result = -EINVAL; - if ( file_permission(filp, MAY_READ) != 0 ) - { + if (file_permission(filp, MAY_READ) != 0) { udf_debug("no permission to access inode %lu\n", - inode->i_ino); + inode->i_ino); return -EPERM; } - if ( !arg ) - { + if (!arg) { udf_debug("invalid argument to udf_ioctl\n"); return -EINVAL; } - switch (cmd) - { - case UDF_GETVOLIDENT: - return copy_to_user((char __user *)arg, - UDF_SB_VOLIDENT(inode->i_sb), 32) ? -EFAULT : 0; - case UDF_RELOCATE_BLOCKS: - { - long old, new; - - if (!capable(CAP_SYS_ADMIN)) return -EACCES; - if (get_user(old, (long __user *)arg)) return -EFAULT; - if ((result = udf_relocate_blocks(inode->i_sb, - old, &new)) == 0) - result = put_user(new, (long __user *)arg); - - return result; - } - case UDF_GETEASIZE: - result = put_user(UDF_I_LENEATTR(inode), (int __user *)arg); - break; - - case UDF_GETEABLOCK: - result = copy_to_user((char __user *)arg, UDF_I_DATA(inode), - UDF_I_LENEATTR(inode)) ? -EFAULT : 0; - break; + switch (cmd) { + case UDF_GETVOLIDENT: + return copy_to_user((char __user *)arg, + UDF_SB_VOLIDENT(inode->i_sb), 32) ? -EFAULT : 0; + case UDF_RELOCATE_BLOCKS: + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + if (get_user(old_block, (long __user *)arg)) + return -EFAULT; + if ((result = udf_relocate_blocks(inode->i_sb, + old_block, &new_block)) == 0) + result = put_user(new_block, (long __user *)arg); + return result; + case UDF_GETEASIZE: + result = put_user(UDF_I_LENEATTR(inode), (int __user *)arg); + break; + case UDF_GETEABLOCK: + result = copy_to_user((char __user *)arg, UDF_I_DATA(inode), + UDF_I_LENEATTR(inode)) ? -EFAULT : 0; + break; } return result; @@ -240,10 +226,9 @@ int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, * HISTORY * */ -static int udf_release_file(struct inode * inode, struct file * filp) +static int udf_release_file(struct inode *inode, struct file *filp) { - if (filp->f_mode & FMODE_WRITE) - { + if (filp->f_mode & FMODE_WRITE) { lock_kernel(); udf_discard_prealloc(inode); unlock_kernel(); @@ -265,5 +250,5 @@ const struct file_operations udf_file_operations = { }; const struct inode_operations udf_file_inode_operations = { - .truncate = udf_truncate, + .truncate = udf_truncate, };