* better
[mascara-docs.git] / i386 / linux-2.3.21 / 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 typedef void * poll_table;
49 static long long udf_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 int udf_open_file(struct inode *, struct file *);
54 #endif
55 static int udf_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 long udf_file_llseek(struct file * file, long long offset, int origin)
156 struct inode * inode = file->f_dentry->d_inode;
158 switch (origin)
160 case 2:
162 offset += inode->i_size;
163 break;
165 case 1:
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 static inline void remove_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 return 0;
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 return 0;
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 int udf_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 int udf_release_file(struct inode * inode, struct file * filp)
416 if (filp->f_mode & FMODE_WRITE)
417 udf_discard_prealloc(inode);
418 return 0;
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 int udf_open_file(struct inode * inode, struct file * filp)
436 if (inode->i_size == (Uint32)-1 && (filp->f_mode & FMODE_WRITE))
437 return -EFBIG;
438 return 0;
440 #endif