File: /usr/src/linux/fs/udf/file.c

1     /*
2      * file.c
3      *
4      * PURPOSE
5      *  File handling routines for the OSTA-UDF(tm) filesystem.
6      *
7      * CONTACTS
8      *  E-mail regarding any portion of the Linux UDF file system should be
9      *  directed to the development team mailing list (run by majordomo):
10      *    linux_udf@hpesjro.fc.hp.com
11      *
12      * COPYRIGHT
13      *  This file is distributed under the terms of the GNU General Public
14      *  License (GPL). Copies of the GPL can be obtained from:
15      *    ftp://prep.ai.mit.edu/pub/gnu/GPL
16      *  Each contributing author retains all rights to their own work.
17      *
18      *  (C) 1998-1999 Dave Boynton
19      *  (C) 1998-2000 Ben Fennema
20      *  (C) 1999-2000 Stelias Computing Inc
21      *
22      * HISTORY
23      *
24      *  10/02/98 dgb  Attempt to integrate into udf.o
25      *  10/07/98      Switched to using generic_readpage, etc., like isofs
26      *                And it works!
27      *  12/06/98 blf  Added udf_file_read. uses generic_file_read for all cases but
28      *                ICB_FLAG_AD_IN_ICB.
29      *  04/06/99      64 bit file handling on 32 bit systems taken from ext2 file.c
30      *  05/12/99      Preliminary file write support
31      */
32     
33     #include "udfdecl.h"
34     #include <linux/fs.h>
35     #include <linux/udf_fs.h>
36     #include <asm/uaccess.h>
37     #include <linux/kernel.h>
38     #include <linux/string.h> /* memset */
39     #include <linux/errno.h>
40     #include <linux/locks.h>
41     #include <linux/smp_lock.h>
42     
43     #include "udf_i.h"
44     #include "udf_sb.h"
45     
46     static int udf_adinicb_readpage(struct file *file, struct page * page)
47     {
48     	struct inode *inode = page->mapping->host;
49     
50     	struct buffer_head *bh;
51     	int block;
52     	char *kaddr;
53     
54     	if (!PageLocked(page))
55     		PAGE_BUG(page);
56     
57     	kaddr = kmap(page);
58     	memset(kaddr, 0, PAGE_CACHE_SIZE);
59     	block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0);
60     	bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize);
61     	memcpy(kaddr, bh->b_data + udf_ext0_offset(inode), inode->i_size);
62     	brelse(bh);
63     	flush_dcache_page(page);
64     	SetPageUptodate(page);
65     	kunmap(page);
66     	UnlockPage(page);
67     	return 0;
68     }
69     
70     static int udf_adinicb_writepage(struct page *page)
71     {
72     	struct inode *inode = page->mapping->host;
73     
74     	struct buffer_head *bh;
75     	int block;
76     	char *kaddr;
77     
78     	if (!PageLocked(page))
79     		PAGE_BUG(page);
80     
81     	kaddr = kmap(page);
82     	block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0);
83     	bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize);
84     	memcpy(bh->b_data + udf_ext0_offset(inode), kaddr, inode->i_size);
85     	mark_buffer_dirty(bh);
86     	brelse(bh);
87     	SetPageUptodate(page);
88     	kunmap(page);
89     	UnlockPage(page);
90     	return 0;
91     }
92     
93     static int udf_adinicb_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
94     {
95     	kmap(page);
96     	return 0;
97     }
98     
99     static int udf_adinicb_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to)
100     {
101     	struct inode *inode = page->mapping->host;
102     
103     	struct buffer_head *bh;
104     	int block;
105     	char *kaddr = page_address(page);
106     
107     	block = udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0);
108     	bh = bread (inode->i_dev, block, inode->i_sb->s_blocksize);
109     	memcpy(bh->b_data + udf_file_entry_alloc_offset(inode) + offset,
110     		kaddr + offset, to-offset);
111     	mark_buffer_dirty(bh);
112     	brelse(bh);
113     	SetPageUptodate(page);
114     	kunmap(page);
115     	/* only one page here */
116     	if (to > inode->i_size)
117     		inode->i_size = to;
118     	return 0;
119     }
120     
121     struct address_space_operations udf_adinicb_aops = {
122     	readpage:		udf_adinicb_readpage,
123     	writepage:		udf_adinicb_writepage,
124     	sync_page:		block_sync_page,
125     	prepare_write:		udf_adinicb_prepare_write,
126     	commit_write:		udf_adinicb_commit_write,
127     };
128     
129     static ssize_t udf_file_write(struct file * file, const char * buf,
130     	size_t count, loff_t *ppos)
131     {
132     	ssize_t retval;
133     	struct inode *inode = file->f_dentry->d_inode;
134     	int err, pos;
135     
136     	if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
137     	{
138     		if (file->f_flags & O_APPEND)
139     			pos = inode->i_size;
140     		else
141     			pos = *ppos;
142     
143     		if (inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) +
144     			pos + count))
145     		{
146     			udf_expand_file_adinicb(inode, pos + count, &err);
147     			if (UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
148     			{
149     				udf_debug("udf_expand_adinicb: err=%d\n", err);
150     				return err;
151     			}
152     		}
153     		else
154     		{
155     			if (pos + count > inode->i_size)
156     				UDF_I_LENALLOC(inode) = pos + count;
157     			else
158     				UDF_I_LENALLOC(inode) = inode->i_size;
159     		}
160     	}
161     
162     	retval = generic_file_write(file, buf, count, ppos);
163     
164     	if (retval > 0)
165     	{
166     		UDF_I_UCTIME(inode) = UDF_I_UMTIME(inode) = CURRENT_UTIME;
167     		mark_inode_dirty(inode);
168     	}
169     	return retval;
170     }
171     
172     /*
173      * udf_ioctl
174      *
175      * PURPOSE
176      *	Issue an ioctl.
177      *
178      * DESCRIPTION
179      *	Optional - sys_ioctl() will return -ENOTTY if this routine is not
180      *	available, and the ioctl cannot be handled without filesystem help.
181      *
182      *	sys_ioctl() handles these ioctls that apply only to regular files:
183      *		FIBMAP [requires udf_block_map()], FIGETBSZ, FIONREAD
184      *	These ioctls are also handled by sys_ioctl():
185      *		FIOCLEX, FIONCLEX, FIONBIO, FIOASYNC
186      *	All other ioctls are passed to the filesystem.
187      *
188      *	Refer to sys_ioctl() in fs/ioctl.c
189      *	sys_ioctl() -> .
190      *
191      * PRE-CONDITIONS
192      *	inode			Pointer to inode that ioctl was issued on.
193      *	filp			Pointer to file that ioctl was issued on.
194      *	cmd			The ioctl command.
195      *	arg			The ioctl argument [can be interpreted as a
196      *				user-space pointer if desired].
197      *
198      * POST-CONDITIONS
199      *	<return>		Success (>=0) or an error code (<=0) that
200      *				sys_ioctl() will return.
201      *
202      * HISTORY
203      *	July 1, 1997 - Andrew E. Mileski
204      *	Written, tested, and released.
205      */
206     int udf_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
207     	unsigned long arg)
208     {
209     	int result = -1;
210     	struct buffer_head *bh = NULL;
211     	long_ad eaicb;
212     	Uint8 *ea = NULL;
213     
214     	if ( permission(inode, MAY_READ) != 0 )
215     	{
216     		udf_debug("no permission to access inode %lu\n",
217     						inode->i_ino);
218     		return -EPERM;
219     	}
220     
221     	if ( !arg )
222     	{
223     		udf_debug("invalid argument to udf_ioctl\n");
224     		return -EINVAL;
225     	}
226     
227     	/* first, do ioctls that don't need to udf_read */
228     	switch (cmd)
229     	{
230     		case UDF_GETVOLIDENT:
231     			if ( (result == verify_area(VERIFY_WRITE, (char *)arg, 32)) == 0)
232     				result = copy_to_user((char *)arg, UDF_SB_VOLIDENT(inode->i_sb), 32);
233     			return result;
234     		case UDF_RELOCATE_BLOCKS:
235     		{
236     			long old, new;
237     
238     			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
239     			get_user(old, (long *)arg);
240     			if ((result = udf_relocate_blocks(inode->i_sb, old, &new)) == 0)
241     				result = put_user(new, (long *)arg);
242     
243     			return result;
244     		}
245     	}
246     
247     	/* ok, we need to read the inode */
248     	bh = udf_tread(inode->i_sb,
249     		udf_get_lb_pblock(inode->i_sb, UDF_I_LOCATION(inode), 0),
250     		inode->i_sb->s_blocksize);
251     
252     	if (!bh)
253     	{
254     		udf_debug("bread failed (inode=%ld)\n", inode->i_ino);
255     		return -EIO;
256     	}
257     
258     	if (UDF_I_EXTENDED_FE(inode) == 0)
259     	{
260     		struct FileEntry *fe;
261     
262     		fe = (struct FileEntry *)bh->b_data;
263     		eaicb = lela_to_cpu(fe->extendedAttrICB);
264     		if (UDF_I_LENEATTR(inode))
265     			ea = fe->extendedAttr;
266     	}
267     	else
268     	{
269     		struct ExtendedFileEntry *efe;
270     
271     		efe = (struct ExtendedFileEntry *)bh->b_data;
272     		eaicb = lela_to_cpu(efe->extendedAttrICB);
273     		if (UDF_I_LENEATTR(inode))
274     			ea = efe->extendedAttr;
275     	}
276     
277     	switch (cmd) 
278     	{
279     		case UDF_GETEASIZE:
280     			if ( (result = verify_area(VERIFY_WRITE, (char *)arg, 4)) == 0) 
281     				result = put_user(UDF_I_LENEATTR(inode), (int *)arg);
282     			break;
283     
284     		case UDF_GETEABLOCK:
285     			if ( (result = verify_area(VERIFY_WRITE, (char *)arg, UDF_I_LENEATTR(inode))) == 0) 
286     				result = copy_to_user((char *)arg, ea, UDF_I_LENEATTR(inode));
287     			break;
288     
289     		default:
290     			break;
291     	}
292     
293     	udf_release_data(bh);
294     	return result;
295     }
296     
297     /*
298      * udf_release_file
299      *
300      * PURPOSE
301      *  Called when all references to the file are closed
302      *
303      * DESCRIPTION
304      *  Discard prealloced blocks
305      *
306      * HISTORY
307      *
308      */
309     static int udf_release_file(struct inode * inode, struct file * filp)
310     {
311     	if (filp->f_mode & FMODE_WRITE)
312     	{
313     		lock_kernel();
314     		udf_discard_prealloc(inode);
315     		unlock_kernel();
316     	}
317     	return 0;
318     }
319     
320     /*
321      * udf_open_file
322      *
323      * PURPOSE
324      *  Called when an inode is about to be open.
325      *
326      * DESCRIPTION
327      *  Use this to disallow opening RW large files on 32 bit systems.
328      *  On 64 bit systems we force on O_LARGEFILE in sys_open.
329      *
330      * HISTORY
331      *
332      */
333     static int udf_open_file(struct inode * inode, struct file * filp)
334     {
335     	if ((inode->i_size & 0xFFFFFFFF80000000ULL) && !(filp->f_flags & O_LARGEFILE))
336     		return -EFBIG;
337     	return 0;
338     }
339     
340     struct file_operations udf_file_operations = {
341     	read:			generic_file_read,
342     	ioctl:			udf_ioctl,
343     	open:			udf_open_file,
344     	mmap:			generic_file_mmap,
345     	write:			udf_file_write,
346     	release:		udf_release_file,
347     	fsync:			udf_fsync_file,
348     };
349     
350     struct inode_operations udf_file_inode_operations = {
351     	truncate:		udf_truncate,
352     };
353