Import 2.3.18pre1
[davej-history.git] / fs / udf / file.c
blob28246684134b2d60ab0bf211b66c7f41a91a5387
1 /*
2 * file.c
4 * PURPOSE
5 * File handling routines for the OSTA-UDF(tm) filesystem.
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@hootie.lvld.hp.com
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.
18 * (C) 1998-1999 Dave Boynton
19 * (C) 1998-1999 Ben Fennema
20 * (C) 1999 Stelias Computing Inc
22 * HISTORY
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
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>
42 #include"udf_i.h"
43 #include"udf_sb.h"
45 #define NBUF 32
47 typedefvoid* poll_table;
49 static long longudf_file_llseek(struct file *,long long,int);
50 static ssize_t udf_file_read_adinicb(struct file *,char*,size_t, loff_t *);
51 static ssize_t udf_file_write(struct file *,const char*,size_t, loff_t *);
52 #if BITS_PER_LONG < 64
53 static intudf_open_file(struct inode *,struct file *);
54 #endif
55 static intudf_release_file(struct inode *,struct file *);
57 static struct file_operations udf_file_operations = {
58 udf_file_llseek,/* llseek */
59 generic_file_read,/* read */
60 udf_file_write,/* write */
61 NULL,/* readdir */
62 NULL,/* poll */
63 udf_ioctl,/* ioctl */
64 generic_file_mmap,/* mmap */
65 #if BITS_PER_LONG == 64
66 NULL,/* open */
67 #else
68 udf_open_file,/* open */
69 #endif
70 NULL,/* flush */
71 udf_release_file,/* release */
72 udf_sync_file,/* fsync */
73 NULL,/* fasync */
74 NULL,/* check_media_change */
75 NULL,/* revalidate */
76 NULL /* lock */
79 struct inode_operations udf_file_inode_operations = {
80 &udf_file_operations,
81 NULL,/* create */
82 NULL,/* lookup */
83 NULL,/* link */
84 NULL,/* unlink */
85 NULL,/* symlink */
86 NULL,/* mkdir */
87 NULL,/* rmdir */
88 NULL,/* mknod */
89 NULL,/* rename */
90 NULL,/* readlink */
91 NULL,/* follow_link */
92 udf_get_block,/* get_block */
93 block_read_full_page,/* readpage */
94 block_write_full_page,/* writepage */
95 block_flushpage,/* flushpage */
96 #ifdef CONFIG_UDF_RW
97 udf_truncate,/* truncate */
98 #else
99 NULL,/* truncate */
100 #endif
101 NULL,/* permission */
102 NULL,/* smap */
103 NULL /* revalidate */
106 static struct file_operations udf_file_operations_adinicb = {
107 udf_file_llseek,/* llseek */
108 udf_file_read_adinicb,/* read */
109 udf_file_write,/* write */
110 NULL,/* readdir */
111 NULL,/* poll */
112 udf_ioctl,/* ioctl */
113 NULL,/* mmap */
114 NULL,/* open */
115 NULL,/* flush */
116 udf_release_file,/* release */
117 udf_sync_file,/* fsync */
118 NULL,/* fasync */
119 NULL,/* check_media_change */
120 NULL,/* revalidate */
121 NULL /* lock */
124 struct inode_operations udf_file_inode_operations_adinicb = {
125 &udf_file_operations_adinicb,
126 NULL,/* create */
127 NULL,/* lookup */
128 NULL,/* link */
129 NULL,/* unlink */
130 NULL,/* symlink */
131 NULL,/* mkdir */
132 NULL,/* rmdir */
133 NULL,/* mknod */
134 NULL,/* rename */
135 NULL,/* readlink */
136 NULL,/* follow_link */
137 udf_get_block,/* get_block */
138 block_read_full_page,/* readpage */
139 block_write_full_page,/* writepage */
140 block_flushpage,/* flushpage */
141 #ifdef CONFIG_UDF_RW
142 udf_truncate,/* truncate */
143 #else
144 NULL,/* truncate */
145 #endif
146 NULL,/* permission */
147 NULL,/* smap */
148 NULL /* revalidate */
152 * Make sure the offset never goes beyond the 32-bit mark..
154 static long longudf_file_llseek(struct file * file,long long offset,int origin)
156 struct inode * inode = file->f_dentry->d_inode;
158 switch(origin)
160 case2:
162 offset += inode->i_size;
163 break;
165 case1:
167 offset += file->f_pos;
168 break;
171 #if BITS_PER_LONG < 64
172 if(((unsigned long long) offset >>32) !=0)
174 return-EINVAL;
176 #endif
177 if(offset != file->f_pos)
179 file->f_pos = offset;
180 file->f_reada =0;
181 file->f_version = ++event;
183 return offset;
186 staticinlinevoidremove_suid(struct inode * inode)
188 unsigned int mode;
190 /* set S_IGID if S_IXGRP is set, and always set S_ISUID */
191 mode = (inode->i_mode & S_IXGRP)*(S_ISGID/S_IXGRP) | S_ISUID;
193 /* was any of the uid bits set? */
194 mode &= inode->i_mode;
195 if(mode && !capable(CAP_FSETID))
197 inode->i_mode &= ~mode;
198 mark_inode_dirty(inode);
202 static ssize_t udf_file_write(struct file * file,const char* buf,
203 size_t count, loff_t *ppos)
205 ssize_t retval;
206 struct inode *inode = file->f_dentry->d_inode;
207 remove_suid(inode);
209 if(UDF_I_ALLOCTYPE(inode) == ICB_FLAG_AD_IN_ICB)
211 int i, err;
212 struct buffer_head *bh;
214 if((bh =udf_expand_adinicb(inode, &i,0, &err)))
215 udf_release_data(bh);
218 retval =generic_file_write(file, buf, count, ppos, block_write_partial_page);
220 if(retval >0)
222 inode->i_ctime = inode->i_mtime = CURRENT_TIME;
223 UDF_I_UCTIME(inode) =UDF_I_UMTIME(inode) = CURRENT_UTIME;
225 mark_inode_dirty(inode);
226 return retval;
230 * udf_file_read
232 * PURPOSE
233 * Read from an open file.
235 * DESCRIPTION
236 * Optional - sys_read() will return -EINVAL if this routine is not
237 * available.
239 * Refer to sys_read() in fs/read_write.c
240 * sys_read() -> .
242 * Note that you can use generic_file_read() instead, which requires that
243 * udf_readpage() be available, but you can use generic_readpage(), which
244 * requires that udf_block_map() be available. Reading will then be done by
245 * memory-mapping the file a page at a time. This is not suitable for
246 * devices that don't handle read-ahead [example: CD-R/RW that may have
247 * blank sectors that shouldn't be read].
249 * Refer to generic_file_read() in mm/filemap.c and to generic_readpage()
250 * in fs/buffer.c
252 * Block devices can use block_read() instead. Refer to fs/block_dev.c
254 * PRE-CONDITIONS
255 * inode Pointer to inode to read from (never NULL).
256 * filp Pointer to file to read from (never NULL).
257 * buf Point to read buffer (validated).
258 * bufsize Size of read buffer.
260 * POST-CONDITIONS
261 * <return> Bytes read (>=0) or an error code (<0) that
262 * sys_read() will return.
264 * HISTORY
265 * July 1, 1997 - Andrew E. Mileski
266 * Written, tested, and released.
268 static ssize_t udf_file_read_adinicb(struct file * filp,char* buf,
269 size_t bufsize, loff_t * loff)
271 struct inode *inode = filp->f_dentry->d_inode;
272 Uint32 size, left, pos, block;
273 struct buffer_head *bh = NULL;
275 size = inode->i_size;
276 if(*loff > size)
277 left =0;
278 else
279 left = size - *loff;
280 if(left > bufsize)
281 left = bufsize;
283 if(left <=0)
284 return0;
286 pos = *loff +UDF_I_EXT0OFFS(inode);
287 block =udf_block_map(inode,0);
288 if(!(bh =udf_tread(inode->i_sb,
289 udf_get_lb_pblock(inode->i_sb,UDF_I_LOCATION(inode),0),
290 inode->i_sb->s_blocksize)))
292 return0;
294 if(!copy_to_user(buf, bh->b_data + pos, left))
295 *loff += left;
296 else
297 return-EFAULT;
299 return left;
303 * udf_ioctl
305 * PURPOSE
306 * Issue an ioctl.
308 * DESCRIPTION
309 * Optional - sys_ioctl() will return -ENOTTY if this routine is not
310 * available, and the ioctl cannot be handled without filesystem help.
312 * sys_ioctl() handles these ioctls that apply only to regular files:
313 * FIBMAP [requires udf_block_map()], FIGETBSZ, FIONREAD
314 * These ioctls are also handled by sys_ioctl():
315 * FIOCLEX, FIONCLEX, FIONBIO, FIOASYNC
316 * All other ioctls are passed to the filesystem.
318 * Refer to sys_ioctl() in fs/ioctl.c
319 * sys_ioctl() -> .
321 * PRE-CONDITIONS
322 * inode Pointer to inode that ioctl was issued on.
323 * filp Pointer to file that ioctl was issued on.
324 * cmd The ioctl command.
325 * arg The ioctl argument [can be interpreted as a
326 * user-space pointer if desired].
328 * POST-CONDITIONS
329 * <return> Success (>=0) or an error code (<=0) that
330 * sys_ioctl() will return.
332 * HISTORY
333 * July 1, 1997 - Andrew E. Mileski
334 * Written, tested, and released.
336 intudf_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,
337 unsigned long arg)
339 int result=-1;
340 int size;
341 struct buffer_head *bh = NULL;
342 struct FileEntry *fe;
343 Uint16 ident;
345 if(permission(inode, MAY_READ) !=0)
347 udf_debug("no permission to access inode %lu\n",
348 inode->i_ino);
349 return-EPERM;
352 if( !arg )
354 udf_debug("invalid argument to udf_ioctl\n");
355 return-EINVAL;
358 /* first, do ioctls that don't need to udf_read */
359 switch(cmd)
361 case UDF_GETVOLIDENT:
362 if( (result ==verify_area(VERIFY_WRITE, (char*)arg,32)) ==0)
363 result =copy_to_user((char*)arg,UDF_SB_VOLIDENT(inode->i_sb),32);
364 return result;
368 /* ok, we need to read the inode */
369 bh =udf_read_ptagged(inode->i_sb,UDF_I_LOCATION(inode),0, &ident);
371 if(!bh || ident != TID_FILE_ENTRY)
373 udf_debug("bread failed (ino=%ld) or ident (%d) != TID_FILE_ENTRY",
374 inode->i_ino, ident);
375 return-EFAULT;
378 fe = (struct FileEntry *)bh->b_data;
379 size =le32_to_cpu(fe->lengthExtendedAttr);
381 switch(cmd)
383 case UDF_GETEASIZE:
384 if( (result =verify_area(VERIFY_WRITE, (char*)arg,4)) ==0)
385 result=put_user(size, (int*)arg);
386 break;
388 case UDF_GETEABLOCK:
389 if( (result =verify_area(VERIFY_WRITE, (char*)arg, size)) ==0)
390 result=copy_to_user((char*)arg, fe->extendedAttr, size);
391 break;
393 default:
394 udf_debug("ino=%ld, cmd=%d\n", inode->i_ino, cmd);
395 break;
398 udf_release_data(bh);
399 return result;
403 * udf_release_file
405 * PURPOSE
406 * Called when all references to the file are closed
408 * DESCRIPTION
409 * Discard prealloced blocks
411 * HISTORY
414 static intudf_release_file(struct inode * inode,struct file * filp)
416 if(filp->f_mode & FMODE_WRITE)
417 udf_discard_prealloc(inode);
418 return0;
421 #if BITS_PER_LONG < 64
423 * udf_open_file
425 * PURPOSE
426 * Called when an inode is about to be open.
428 * DESCRIPTION
429 * Use this to disallow opening RW large files on 32 bit systems.
431 * HISTORY
434 static intudf_open_file(struct inode * inode,struct file * filp)
436 if(inode->i_size == (Uint32)-1&& (filp->f_mode & FMODE_WRITE))
437 return-EFBIG;
438 return0;
440 #endif
close