11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * file.c
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PURPOSE
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  File handling routines for the OSTA-UDF(tm) filesystem.
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * COPYRIGHT
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  This file is distributed under the terms of the GNU General Public
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  License (GPL). Copies of the GPL can be obtained from:
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *    ftp://prep.ai.mit.edu/pub/gnu/GPL
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  Each contributing author retains all rights to their own work.
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  (C) 1998-1999 Dave Boynton
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  (C) 1998-2004 Ben Fennema
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  (C) 1999-2000 Stelias Computing Inc
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * HISTORY
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  10/02/98 dgb  Attempt to integrate into udf.o
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  10/07/98      Switched to using generic_readpage, etc., like isofs
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *                And it works!
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  12/06/98 blf  Added udf_file_read. uses generic_file_read for all cases but
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *                ICBTAG_FLAG_AD_IN_ICB.
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  04/06/99      64 bit file handling on 32 bit systems taken from ext2 file.c
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *  05/12/99      Preliminary file write support
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "udfdecl.h"
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/fs.h>
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/uaccess.h>
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h>
3228de7948a896763bc97ccd416bba5b9422158350Cyrill Gorcunov#include <linux/string.h> /* memset */
3316f7e0fe2ecc30f30652e8185e1772cdebe39109Randy Dunlap#include <linux/capability.h>
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/errno.h>
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/pagemap.h>
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/buffer_head.h>
37e8edc6e03a5c8562dc70a6d969f732bdb355a7e7Alexey Dobriyan#include <linux/aio.h>
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "udf_i.h"
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "udf_sb.h"
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
42cb00ea3528eb3c09eae9871d6e7d038776e952e2Cyrill Gorcunovstatic int udf_adinicb_readpage(struct file *file, struct page *page)
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct inode *inode = page->mapping->host;
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *kaddr;
4648d6d8ff7dca804536298e517298182c4a51c421Marcin Slusarz	struct udf_inode_info *iinfo = UDF_I(inode);
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
48cd7619d6bf36564cf54ff7218ef54e558a741913Matt Mackall	BUG_ON(!PageLocked(page));
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kaddr = kmap(page);
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memset(kaddr, 0, PAGE_CACHE_SIZE);
5248d6d8ff7dca804536298e517298182c4a51c421Marcin Slusarz	memcpy(kaddr, iinfo->i_ext.i_data + iinfo->i_lenEAttr, inode->i_size);
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	flush_dcache_page(page);
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	SetPageUptodate(page);
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kunmap(page);
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unlock_page(page);
5728de7948a896763bc97ccd416bba5b9422158350Cyrill Gorcunov
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
614b11111aba6c80cc2969fd1806d2a869bfc9f357Marcin Slusarzstatic int udf_adinicb_writepage(struct page *page,
624b11111aba6c80cc2969fd1806d2a869bfc9f357Marcin Slusarz				 struct writeback_control *wbc)
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct inode *inode = page->mapping->host;
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char *kaddr;
6648d6d8ff7dca804536298e517298182c4a51c421Marcin Slusarz	struct udf_inode_info *iinfo = UDF_I(inode);
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
68cd7619d6bf36564cf54ff7218ef54e558a741913Matt Mackall	BUG_ON(!PageLocked(page));
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kaddr = kmap(page);
7148d6d8ff7dca804536298e517298182c4a51c421Marcin Slusarz	memcpy(iinfo->i_ext.i_data + iinfo->i_lenEAttr, kaddr, inode->i_size);
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mark_inode_dirty(inode);
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	SetPageUptodate(page);
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kunmap(page);
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unlock_page(page);
7628de7948a896763bc97ccd416bba5b9422158350Cyrill Gorcunov
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
80be021ee41a8b65d181fe22799de6be62adf72efbNick Pigginstatic int udf_adinicb_write_end(struct file *file,
81be021ee41a8b65d181fe22799de6be62adf72efbNick Piggin			struct address_space *mapping,
82be021ee41a8b65d181fe22799de6be62adf72efbNick Piggin			loff_t pos, unsigned len, unsigned copied,
83be021ee41a8b65d181fe22799de6be62adf72efbNick Piggin			struct page *page, void *fsdata)
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
85be021ee41a8b65d181fe22799de6be62adf72efbNick Piggin	struct inode *inode = mapping->host;
86be021ee41a8b65d181fe22799de6be62adf72efbNick Piggin	unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
87be021ee41a8b65d181fe22799de6be62adf72efbNick Piggin	char *kaddr;
8848d6d8ff7dca804536298e517298182c4a51c421Marcin Slusarz	struct udf_inode_info *iinfo = UDF_I(inode);
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
90be021ee41a8b65d181fe22799de6be62adf72efbNick Piggin	kaddr = kmap_atomic(page, KM_USER0);
9148d6d8ff7dca804536298e517298182c4a51c421Marcin Slusarz	memcpy(iinfo->i_ext.i_data + iinfo->i_lenEAttr + offset,
92be021ee41a8b65d181fe22799de6be62adf72efbNick Piggin		kaddr + offset, copied);
93be021ee41a8b65d181fe22799de6be62adf72efbNick Piggin	kunmap_atomic(kaddr, KM_USER0);
94be021ee41a8b65d181fe22799de6be62adf72efbNick Piggin
95be021ee41a8b65d181fe22799de6be62adf72efbNick Piggin	return simple_write_end(file, mapping, pos, len, copied, page, fsdata);
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
98f5e54d6e53a20cef45af7499e86164f0e0d16bb2Christoph Hellwigconst struct address_space_operations udf_adinicb_aops = {
9928de7948a896763bc97ccd416bba5b9422158350Cyrill Gorcunov	.readpage	= udf_adinicb_readpage,
10028de7948a896763bc97ccd416bba5b9422158350Cyrill Gorcunov	.writepage	= udf_adinicb_writepage,
101be021ee41a8b65d181fe22799de6be62adf72efbNick Piggin	.write_begin = simple_write_begin,
102be021ee41a8b65d181fe22799de6be62adf72efbNick Piggin	.write_end = udf_adinicb_write_end,
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
105543ade1fc901db4c3dbe9fb27241fb977f1f3eeaBadari Pulavartystatic ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
106cb00ea3528eb3c09eae9871d6e7d038776e952e2Cyrill Gorcunov				  unsigned long nr_segs, loff_t ppos)
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ssize_t retval;
109543ade1fc901db4c3dbe9fb27241fb977f1f3eeaBadari Pulavarty	struct file *file = iocb->ki_filp;
1105096e933a943c23bd9314b0ac7e14d07073cb2e5Josef Sipek	struct inode *inode = file->f_path.dentry->d_inode;
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int err, pos;
112543ade1fc901db4c3dbe9fb27241fb977f1f3eeaBadari Pulavarty	size_t count = iocb->ki_left;
11348d6d8ff7dca804536298e517298182c4a51c421Marcin Slusarz	struct udf_inode_info *iinfo = UDF_I(inode);
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1158754a3f718f08dc21b3c5eccd044f612d4bc1ab1Jan Kara	down_write(&iinfo->i_data_sem);
11648d6d8ff7dca804536298e517298182c4a51c421Marcin Slusarz	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (file->f_flags & O_APPEND)
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			pos = inode->i_size;
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		else
120543ade1fc901db4c3dbe9fb27241fb977f1f3eeaBadari Pulavarty			pos = ppos;
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1224b11111aba6c80cc2969fd1806d2a869bfc9f357Marcin Slusarz		if (inode->i_sb->s_blocksize <
1234b11111aba6c80cc2969fd1806d2a869bfc9f357Marcin Slusarz				(udf_file_entry_alloc_offset(inode) +
12428de7948a896763bc97ccd416bba5b9422158350Cyrill Gorcunov						pos + count)) {
1257e49b6f2480cb9a9e7322a91592e56a5c85361f5Jan Kara			err = udf_expand_file_adinicb(inode);
1267e49b6f2480cb9a9e7322a91592e56a5c85361f5Jan Kara			if (err) {
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				udf_debug("udf_expand_adinicb: err=%d\n", err);
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				return err;
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
130cb00ea3528eb3c09eae9871d6e7d038776e952e2Cyrill Gorcunov		} else {
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (pos + count > inode->i_size)
13248d6d8ff7dca804536298e517298182c4a51c421Marcin Slusarz				iinfo->i_lenAlloc = pos + count;
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			else
13448d6d8ff7dca804536298e517298182c4a51c421Marcin Slusarz				iinfo->i_lenAlloc = inode->i_size;
135d2eb8c359309ec45d6bf5b147303ab8e13be86eaJan Kara			up_write(&iinfo->i_data_sem);
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
137d2eb8c359309ec45d6bf5b147303ab8e13be86eaJan Kara	} else
138d2eb8c359309ec45d6bf5b147303ab8e13be86eaJan Kara		up_write(&iinfo->i_data_sem);
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
140543ade1fc901db4c3dbe9fb27241fb977f1f3eeaBadari Pulavarty	retval = generic_file_aio_write(iocb, iov, nr_segs, ppos);
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (retval > 0)
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		mark_inode_dirty(inode);
14328de7948a896763bc97ccd416bba5b9422158350Cyrill Gorcunov
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return retval;
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1472f07a88b30f510c7625d75cdf286903b465350a0John Kacurlong udf_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1492f07a88b30f510c7625d75cdf286903b465350a0John Kacur	struct inode *inode = filp->f_dentry->d_inode;
15028de7948a896763bc97ccd416bba5b9422158350Cyrill Gorcunov	long old_block, new_block;
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int result = -EINVAL;
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1536f2861097467852f2271c2b40f9c3d1d01757048Al Viro	if (inode_permission(inode, MAY_READ) != 0) {
1542f07a88b30f510c7625d75cdf286903b465350a0John Kacur		udf_debug("no permission to access inode %lu\n", inode->i_ino);
1552f07a88b30f510c7625d75cdf286903b465350a0John Kacur		result = -EPERM;
1562f07a88b30f510c7625d75cdf286903b465350a0John Kacur		goto out;
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
159cb00ea3528eb3c09eae9871d6e7d038776e952e2Cyrill Gorcunov	if (!arg) {
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		udf_debug("invalid argument to udf_ioctl\n");
1612f07a88b30f510c7625d75cdf286903b465350a0John Kacur		result = -EINVAL;
1622f07a88b30f510c7625d75cdf286903b465350a0John Kacur		goto out;
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
165cb00ea3528eb3c09eae9871d6e7d038776e952e2Cyrill Gorcunov	switch (cmd) {
166cb00ea3528eb3c09eae9871d6e7d038776e952e2Cyrill Gorcunov	case UDF_GETVOLIDENT:
1674b11111aba6c80cc2969fd1806d2a869bfc9f357Marcin Slusarz		if (copy_to_user((char __user *)arg,
1684b11111aba6c80cc2969fd1806d2a869bfc9f357Marcin Slusarz				 UDF_SB(inode->i_sb)->s_volume_ident, 32))
1692f07a88b30f510c7625d75cdf286903b465350a0John Kacur			result = -EFAULT;
1704b11111aba6c80cc2969fd1806d2a869bfc9f357Marcin Slusarz		else
1712f07a88b30f510c7625d75cdf286903b465350a0John Kacur			result = 0;
1722f07a88b30f510c7625d75cdf286903b465350a0John Kacur		goto out;
173cb00ea3528eb3c09eae9871d6e7d038776e952e2Cyrill Gorcunov	case UDF_RELOCATE_BLOCKS:
1742f07a88b30f510c7625d75cdf286903b465350a0John Kacur		if (!capable(CAP_SYS_ADMIN)) {
1752f07a88b30f510c7625d75cdf286903b465350a0John Kacur			result = -EACCES;
1762f07a88b30f510c7625d75cdf286903b465350a0John Kacur			goto out;
1772f07a88b30f510c7625d75cdf286903b465350a0John Kacur		}
1782f07a88b30f510c7625d75cdf286903b465350a0John Kacur		if (get_user(old_block, (long __user *)arg)) {
1792f07a88b30f510c7625d75cdf286903b465350a0John Kacur			result = -EFAULT;
1802f07a88b30f510c7625d75cdf286903b465350a0John Kacur			goto out;
1812f07a88b30f510c7625d75cdf286903b465350a0John Kacur		}
1824b11111aba6c80cc2969fd1806d2a869bfc9f357Marcin Slusarz		result = udf_relocate_blocks(inode->i_sb,
1834b11111aba6c80cc2969fd1806d2a869bfc9f357Marcin Slusarz						old_block, &new_block);
1844b11111aba6c80cc2969fd1806d2a869bfc9f357Marcin Slusarz		if (result == 0)
18528de7948a896763bc97ccd416bba5b9422158350Cyrill Gorcunov			result = put_user(new_block, (long __user *)arg);
1862f07a88b30f510c7625d75cdf286903b465350a0John Kacur		goto out;
187cb00ea3528eb3c09eae9871d6e7d038776e952e2Cyrill Gorcunov	case UDF_GETEASIZE:
188c0b344385fa05f6bea462e707fcba89f9e2776c2Marcin Slusarz		result = put_user(UDF_I(inode)->i_lenEAttr, (int __user *)arg);
1892f07a88b30f510c7625d75cdf286903b465350a0John Kacur		goto out;
190cb00ea3528eb3c09eae9871d6e7d038776e952e2Cyrill Gorcunov	case UDF_GETEABLOCK:
191c0b344385fa05f6bea462e707fcba89f9e2776c2Marcin Slusarz		result = copy_to_user((char __user *)arg,
192c0b344385fa05f6bea462e707fcba89f9e2776c2Marcin Slusarz				      UDF_I(inode)->i_ext.i_data,
193c0b344385fa05f6bea462e707fcba89f9e2776c2Marcin Slusarz				      UDF_I(inode)->i_lenEAttr) ? -EFAULT : 0;
1942f07a88b30f510c7625d75cdf286903b465350a0John Kacur		goto out;
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1972f07a88b30f510c7625d75cdf286903b465350a0John Kacurout:
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return result;
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
201cb00ea3528eb3c09eae9871d6e7d038776e952e2Cyrill Gorcunovstatic int udf_release_file(struct inode *inode, struct file *filp)
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
203cb00ea3528eb3c09eae9871d6e7d038776e952e2Cyrill Gorcunov	if (filp->f_mode & FMODE_WRITE) {
204cbc8cc33529b0e0e55ae0ff077b8cb0b71d54c7aJan Kara		mutex_lock(&inode->i_mutex);
2054d0fb621d35007c19a396f2bb629e5aeaacef2d0Alessio Igor Bogani		down_write(&UDF_I(inode)->i_data_sem);
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		udf_discard_prealloc(inode);
2072c948b3f86e5f0327e2e57858600af6e6f0ae29aJan Kara		udf_truncate_tail_extent(inode);
2084d0fb621d35007c19a396f2bb629e5aeaacef2d0Alessio Igor Bogani		up_write(&UDF_I(inode)->i_data_sem);
209cbc8cc33529b0e0e55ae0ff077b8cb0b71d54c7aJan Kara		mutex_unlock(&inode->i_mutex);
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2144b6f5d20b04dcbc3d888555522b90ba6d36c4106Arjan van de Venconst struct file_operations udf_file_operations = {
21528de7948a896763bc97ccd416bba5b9422158350Cyrill Gorcunov	.read			= do_sync_read,
21628de7948a896763bc97ccd416bba5b9422158350Cyrill Gorcunov	.aio_read		= generic_file_aio_read,
2172f07a88b30f510c7625d75cdf286903b465350a0John Kacur	.unlocked_ioctl		= udf_ioctl,
21836350462814739e1f38cba59a6900ebadb08d3bbJan Kara	.open			= generic_file_open,
21928de7948a896763bc97ccd416bba5b9422158350Cyrill Gorcunov	.mmap			= generic_file_mmap,
22028de7948a896763bc97ccd416bba5b9422158350Cyrill Gorcunov	.write			= do_sync_write,
22128de7948a896763bc97ccd416bba5b9422158350Cyrill Gorcunov	.aio_write		= udf_file_aio_write,
22228de7948a896763bc97ccd416bba5b9422158350Cyrill Gorcunov	.release		= udf_release_file,
2231b061d9247f71cd15edc4c4c4600191a903642c0Christoph Hellwig	.fsync			= generic_file_fsync,
22428de7948a896763bc97ccd416bba5b9422158350Cyrill Gorcunov	.splice_read		= generic_file_splice_read,
2255c89468c12899b84886cb47eec93f0c88e0f896aChristoph Hellwig	.llseek			= generic_file_llseek,
2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
228d39aae9ec447dda84d9a2850743a78a535a71c90Christoph Hellwigstatic int udf_setattr(struct dentry *dentry, struct iattr *attr)
229d39aae9ec447dda84d9a2850743a78a535a71c90Christoph Hellwig{
230d39aae9ec447dda84d9a2850743a78a535a71c90Christoph Hellwig	struct inode *inode = dentry->d_inode;
231d39aae9ec447dda84d9a2850743a78a535a71c90Christoph Hellwig	int error;
232d39aae9ec447dda84d9a2850743a78a535a71c90Christoph Hellwig
233d39aae9ec447dda84d9a2850743a78a535a71c90Christoph Hellwig	error = inode_change_ok(inode, attr);
234d39aae9ec447dda84d9a2850743a78a535a71c90Christoph Hellwig	if (error)
235d39aae9ec447dda84d9a2850743a78a535a71c90Christoph Hellwig		return error;
2361025774ce411f2bd4b059ad7b53f0003569b74faChristoph Hellwig
2371025774ce411f2bd4b059ad7b53f0003569b74faChristoph Hellwig	if ((attr->ia_valid & ATTR_SIZE) &&
2381025774ce411f2bd4b059ad7b53f0003569b74faChristoph Hellwig	    attr->ia_size != i_size_read(inode)) {
2397e49b6f2480cb9a9e7322a91592e56a5c85361f5Jan Kara		error = udf_setsize(inode, attr->ia_size);
2401025774ce411f2bd4b059ad7b53f0003569b74faChristoph Hellwig		if (error)
2411025774ce411f2bd4b059ad7b53f0003569b74faChristoph Hellwig			return error;
2421025774ce411f2bd4b059ad7b53f0003569b74faChristoph Hellwig	}
2431025774ce411f2bd4b059ad7b53f0003569b74faChristoph Hellwig
2441025774ce411f2bd4b059ad7b53f0003569b74faChristoph Hellwig	setattr_copy(inode, attr);
2451025774ce411f2bd4b059ad7b53f0003569b74faChristoph Hellwig	mark_inode_dirty(inode);
2461025774ce411f2bd4b059ad7b53f0003569b74faChristoph Hellwig	return 0;
247d39aae9ec447dda84d9a2850743a78a535a71c90Christoph Hellwig}
248d39aae9ec447dda84d9a2850743a78a535a71c90Christoph Hellwig
249c5ef1c42c51b1b5b4a401a6517bdda30933ddbafArjan van de Venconst struct inode_operations udf_file_inode_operations = {
250d39aae9ec447dda84d9a2850743a78a535a71c90Christoph Hellwig	.setattr		= udf_setattr,
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
252