[PATCH] (1/4) 2.5.5-pre1 fixes
[opensuse:kernel.git] / fs / hfs / file.c
1 /*
2  * linux/fs/hfs/file.c
3  *
4  * Copyright (C) 1995, 1996  Paul H. Hargrove
5  * This file may be distributed under the terms of the GNU General Public License.
6  *
7  * This file contains the file-related functions which are independent of
8  * which scheme is being used to represent forks.
9  *
10  * Based on the minix file system code, (C) 1991, 1992 by Linus Torvalds
11  *
12  * "XXX" in a comment is a note to myself to consider changing something.
13  *
14  * In function preconditions the term "valid" applied to a pointer to
15  * a structure means that the pointer is non-NULL and the structure it
16  * points to has all fields initialized to consistent values.
17  */
18
19 #include "hfs.h"
20 #include <linux/hfs_fs_sb.h>
21 #include <linux/hfs_fs_i.h>
22 #include <linux/hfs_fs.h>
23 #include <linux/smp_lock.h>
24
25 /*================ Forward declarations ================*/
26
27 static hfs_rwret_t hfs_file_read(struct file *, char *, hfs_rwarg_t,
28                                  loff_t *);
29 static hfs_rwret_t hfs_file_write(struct file *, const char *, hfs_rwarg_t,
30                                   loff_t *);
31 static void hfs_file_truncate(struct inode *);
32
33 /*================ Global variables ================*/
34
35 struct file_operations hfs_file_operations = {
36         llseek:         generic_file_llseek,
37         read:           hfs_file_read,
38         write:          hfs_file_write,
39         mmap:           generic_file_mmap,
40         fsync:          file_fsync,
41 };
42
43 struct inode_operations hfs_file_inode_operations = {
44         truncate:       hfs_file_truncate,
45         setattr:        hfs_notify_change,
46 };
47
48 /*================ Variable-like macros ================*/
49
50 /* maximum number of blocks to try to read in at once */
51 #define NBUF 32
52
53 /*================ File-local functions ================*/
54
55 /*
56  * hfs_getblk()
57  *
58  * Given an hfs_fork and a block number return the buffer_head for
59  * that block from the fork.  If 'create' is non-zero then allocate
60  * the necessary block(s) to the fork.
61  */
62 struct buffer_head *hfs_getblk(struct hfs_fork *fork, int block, int create)
63 {
64         int tmp;
65         struct super_block *sb = fork->entry->mdb->sys_mdb;
66
67         tmp = hfs_extent_map(fork, block, create);
68
69         if (create) {
70                 /* If writing the block, then we have exclusive access
71                    to the file until we return, so it can't have moved.
72                 */
73                 if (tmp) {
74                         hfs_cat_mark_dirty(fork->entry);
75                         return sb_getblk(sb, tmp);
76                 }
77                 return NULL;
78         } else {
79                 /* If reading the block, then retry since the
80                    location on disk could have changed while
81                    we waited on the I/O in getblk to complete.
82                 */
83                 do {
84                         struct buffer_head *bh = sb_getblk(sb, tmp);
85                         int tmp2 = hfs_extent_map(fork, block, 0);
86
87                         if (tmp2 == tmp) {
88                                 return bh;
89                         } else {
90                                 /* The block moved or no longer exists. */
91                                 brelse(bh);
92                                 tmp = tmp2;
93                         }
94                 } while (tmp != 0);
95
96                 /* The block no longer exists. */
97                 return NULL;
98         }
99 }
100
101 /*
102  * hfs_get_block
103  *
104  * This is the hfs_get_block() field in the inode_operations structure for
105  * "regular" (non-header) files.  The purpose is to translate an inode
106  * and a block number within the corresponding file into a physical
107  * block number.  This function just calls hfs_extent_map() to do the
108  * real work and then stuffs the appropriate info into the buffer_head.
109  */
110 int hfs_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create)
111 {
112         unsigned long phys;
113
114         phys = hfs_extent_map(HFS_I(inode)->fork, iblock, create);
115         if (phys) {
116                 if (create)
117                         bh_result->b_state |= (1UL << BH_New);
118                 map_bh(bh_result, inode->i_sb, phys);
119                 return 0;
120         }
121
122         if (!create)
123                 return 0;
124
125         /* we tried to add stuff, but we couldn't. send back an out-of-space
126          * error. */
127         return -ENOSPC;
128 }
129
130
131 /*
132  * hfs_file_read()
133  *
134  * This is the read field in the inode_operations structure for
135  * "regular" (non-header) files.  The purpose is to transfer up to
136  * 'count' bytes from the file corresponding to 'inode', beginning at
137  * 'filp->offset' bytes into the file.  The data is transferred to
138  * user-space at the address 'buf'.  Returns the number of bytes
139  * successfully transferred.  This function checks the arguments, does
140  * some setup and then calls hfs_do_read() to do the actual transfer.  */
141 static hfs_rwret_t hfs_file_read(struct file * filp, char * buf, 
142                                  hfs_rwarg_t count, loff_t *ppos)
143 {
144         struct inode *inode = filp->f_dentry->d_inode;
145         hfs_s32 read, left, pos, size;
146
147         if (!S_ISREG(inode->i_mode)) {
148                 hfs_warn("hfs_file_read: mode = %07o\n",inode->i_mode);
149                 return -EINVAL;
150         }
151         pos = *ppos;
152         if (pos >= HFS_FORK_MAX) {
153                 return 0;
154         }
155         size = inode->i_size;
156         if (pos > size) {
157                 left = 0;
158         } else {
159                 left = size - pos;
160         }
161         if (left > count) {
162                 left = count;
163         }
164         if (left <= 0) {
165                 return 0;
166         }
167         if ((read = hfs_do_read(inode, HFS_I(inode)->fork, pos, buf, left)) > 0) {
168                 *ppos += read;
169                 filp->f_reada = 1;
170         }
171
172         return read;
173 }
174
175 /*
176  * hfs_file_write()
177  *
178  * This is the write() entry in the file_operations structure for
179  * "regular" files.  The purpose is to transfer up to 'count' bytes
180  * to the file corresponding to 'inode' beginning at offset
181  * 'file->f_pos' from user-space at the address 'buf'.  The return
182  * value is the number of bytes actually transferred.
183  */
184 static hfs_rwret_t hfs_file_write(struct file * filp, const char * buf,
185                                   hfs_rwarg_t count, loff_t *ppos)
186 {
187         struct inode    *inode = filp->f_dentry->d_inode;
188         struct hfs_fork *fork = HFS_I(inode)->fork;
189         hfs_s32 written, pos;
190
191         if (!S_ISREG(inode->i_mode)) {
192                 hfs_warn("hfs_file_write: mode = %07o\n", inode->i_mode);
193                 return -EINVAL;
194         }
195
196         pos = (filp->f_flags & O_APPEND) ? inode->i_size : *ppos;
197
198         if (pos >= HFS_FORK_MAX) {
199                 return 0;
200         }
201         if (count > HFS_FORK_MAX) {
202                 count = HFS_FORK_MAX;
203         }
204         if ((written = hfs_do_write(inode, fork, pos, buf, count)) > 0)
205                 pos += written;
206
207         *ppos = pos;
208         if (*ppos > inode->i_size) {
209                 inode->i_size = *ppos;
210                 mark_inode_dirty(inode);
211         }
212
213         return written;
214 }
215
216 /*
217  * hfs_file_truncate()
218  *
219  * This is the truncate() entry in the file_operations structure for
220  * "regular" files.  The purpose is to change the length of the file
221  * corresponding to the given inode.  Changes can either lengthen or
222  * shorten the file.
223  */
224 static void hfs_file_truncate(struct inode * inode)
225 {
226         struct hfs_fork *fork;
227
228         lock_kernel();
229         fork = HFS_I(inode)->fork;
230         fork->lsize = inode->i_size;
231         hfs_extent_adj(fork);
232         hfs_cat_mark_dirty(HFS_I(inode)->entry);
233
234         inode->i_size = fork->lsize;
235         inode->i_blocks = fork->psize;
236         mark_inode_dirty(inode);
237         unlock_kernel();
238 }
239
240 /*
241  * xlate_to_user()
242  *
243  * Like copy_to_user() while translating CR->NL.
244  */
245 static inline void xlate_to_user(char *buf, const char *data, int count)
246 {
247         char ch;
248
249         while (count--) {
250                 ch = *(data++);
251                 put_user((ch == '\r') ? '\n' : ch, buf++);
252         }
253 }
254
255 /*
256  * xlate_from_user()
257  *
258  * Like copy_from_user() while translating NL->CR;
259  */
260 static inline int xlate_from_user(char *data, const char *buf, int count)
261 {
262         int i;
263
264         i = copy_from_user(data, buf, count);
265         count -= i;
266         while (count--) {
267                 if (*data == '\n') {
268                         *data = '\r';
269                 }
270                 ++data;
271         }
272         return i;
273 }
274
275 /*================ Global functions ================*/
276
277 /*
278  * hfs_do_read()
279  *
280  * This function transfers actual data from disk to user-space memory,
281  * returning the number of bytes successfully transferred.  'fork' tells
282  * which file on the disk to read from.  'pos' gives the offset into
283  * the Linux file at which to begin the transfer.  Note that this will
284  * differ from 'filp->offset' in the case of an AppleDouble header file
285  * due to the block of metadata at the beginning of the file, which has
286  * no corresponding place in the HFS file.  'count' tells how many
287  * bytes to transfer.  'buf' gives an address in user-space to transfer
288  * the data to.
289  * 
290  * This is based on Linus's minix_file_read().
291  * It has been changed to take into account that HFS files have no holes.
292  */
293 hfs_s32 hfs_do_read(struct inode *inode, struct hfs_fork * fork, hfs_u32 pos,
294                     char * buf, hfs_u32 count)
295 {
296         hfs_s32 size, chars, offset, block, blocks, read = 0;
297         int bhrequest, uptodate;
298         int convert = HFS_I(inode)->convert;
299         struct buffer_head ** bhb, ** bhe;
300         struct buffer_head * bhreq[NBUF];
301         struct buffer_head * buflist[NBUF];
302
303         /* split 'pos' in to block and (byte) offset components */
304         block = pos >> HFS_SECTOR_SIZE_BITS;
305         offset = pos & (HFS_SECTOR_SIZE-1);
306
307         /* compute the logical size of the fork in blocks */
308         size = (fork->lsize + (HFS_SECTOR_SIZE-1)) >> HFS_SECTOR_SIZE_BITS;
309
310         /* compute the number of physical blocks to be transferred */
311         blocks = (count+offset+HFS_SECTOR_SIZE-1) >> HFS_SECTOR_SIZE_BITS;
312
313         bhb = bhe = buflist;
314
315         /* We do this in a two stage process.  We first try and
316            request as many blocks as we can, then we wait for the
317            first one to complete, and then we try and wrap up as many
318            as are actually done.
319            
320            This routine is optimized to make maximum use of the
321            various buffers and caches. */
322
323         do {
324                 bhrequest = 0;
325                 uptodate = 1;
326                 while (blocks) {
327                         --blocks;
328                         *bhb = hfs_getblk(fork, block++, 0);
329
330                         if (!(*bhb)) {
331                                 /* Since there are no holes in HFS files
332                                    we must have encountered an error.
333                                    So, stop adding blocks to the queue. */
334                                 blocks = 0;
335                                 break;
336                         }
337
338                         if (!buffer_uptodate(*bhb)) {
339                                 uptodate = 0;
340                                 bhreq[bhrequest++] = *bhb;
341                         }
342
343                         if (++bhb == &buflist[NBUF]) {
344                                 bhb = buflist;
345                         }
346
347                         /* If the block we have on hand is uptodate,
348                            go ahead and complete processing. */
349                         if (uptodate) {
350                                 break;
351                         }
352                         if (bhb == bhe) {
353                                 break;
354                         }
355                 }
356
357                 /* If the only block in the queue is bad then quit */
358                 if (!(*bhe)) {
359                         break;
360                 }
361
362                 /* Now request them all */
363                 if (bhrequest) {
364                         ll_rw_block(READ, bhrequest, bhreq);
365                 }
366
367                 do {  /* Finish off all I/O that has actually completed */
368                         char *p;
369
370                         wait_on_buffer(*bhe);
371
372                         if (!buffer_uptodate(*bhe)) {
373                                 /* read error? */
374                                 brelse(*bhe);
375                                 if (++bhe == &buflist[NBUF]) {
376                                         bhe = buflist;
377                                 }
378                                 count = 0;
379                                 break;
380                         }
381
382                         if (count < HFS_SECTOR_SIZE - offset) {
383                                 chars = count;
384                         } else {
385                                 chars = HFS_SECTOR_SIZE - offset;
386                         }
387                         p = (*bhe)->b_data + offset;
388                         if (convert) {
389                                 xlate_to_user(buf, p, chars);
390                         } else {
391                                 chars -= copy_to_user(buf, p, chars);
392                                 if (!chars) {
393                                         brelse(*bhe);
394                                         count = 0;
395                                         if (!read)
396                                                 read = -EFAULT;
397                                         break;
398                                 }
399                         }
400                         brelse(*bhe);
401                         count -= chars;
402                         buf += chars;
403                         read += chars;
404                         offset = 0;
405                         if (++bhe == &buflist[NBUF]) {
406                                 bhe = buflist;
407                         }
408                 } while (count && (bhe != bhb) && !buffer_locked(*bhe));
409         } while (count);
410
411         /* Release the read-ahead blocks */
412         while (bhe != bhb) {
413                 brelse(*bhe);
414                 if (++bhe == &buflist[NBUF]) {
415                         bhe = buflist;
416                 }
417         }
418         if (!read) {
419                 return -EIO;
420         }
421         return read;
422 }
423  
424 /*
425  * hfs_do_write()
426  *
427  * This function transfers actual data from user-space memory to disk,
428  * returning the number of bytes successfully transferred.  'fork' tells
429  * which file on the disk to write to.  'pos' gives the offset into
430  * the Linux file at which to begin the transfer.  Note that this will
431  * differ from 'filp->offset' in the case of an AppleDouble header file
432  * due to the block of metadata at the beginning of the file, which has
433  * no corresponding place in the HFS file.  'count' tells how many
434  * bytes to transfer.  'buf' gives an address in user-space to transfer
435  * the data from.
436  * 
437  * This is just a minor edit of Linus's minix_file_write().
438  */
439 hfs_s32 hfs_do_write(struct inode *inode, struct hfs_fork * fork, hfs_u32 pos,
440                      const char * buf, hfs_u32 count)
441 {
442         hfs_s32 written, c;
443         struct buffer_head * bh;
444         char * p;
445         int convert = HFS_I(inode)->convert;
446
447         written = 0;
448         while (written < count) {
449                 bh = hfs_getblk(fork, pos/HFS_SECTOR_SIZE, 1);
450                 if (!bh) {
451                         if (!written) {
452                                 written = -ENOSPC;
453                         }
454                         break;
455                 }
456                 c = HFS_SECTOR_SIZE - (pos % HFS_SECTOR_SIZE);
457                 if (c > count - written) {
458                         c = count - written;
459                 }
460                 if (c != HFS_SECTOR_SIZE && !buffer_uptodate(bh)) {
461                         ll_rw_block(READ, 1, &bh);
462                         wait_on_buffer(bh);
463                         if (!buffer_uptodate(bh)) {
464                                 brelse(bh);
465                                 if (!written) {
466                                         written = -EIO;
467                                 }
468                                 break;
469                         }
470                 }
471                 p = (pos % HFS_SECTOR_SIZE) + bh->b_data;
472                 c -= convert ? xlate_from_user(p, buf, c) :
473                         copy_from_user(p, buf, c);
474                 if (!c) {
475                         brelse(bh);
476                         if (!written)
477                                 written = -EFAULT;
478                         break;
479                 }
480                 pos += c;
481                 written += c;
482                 buf += c;
483                 mark_buffer_uptodate(bh, 1);
484                 mark_buffer_dirty(bh);
485                 brelse(bh);
486         }
487         if (written > 0) {
488                 struct hfs_cat_entry *entry = fork->entry;
489
490                 inode->i_mtime = inode->i_ctime = CURRENT_TIME;
491                 if (pos > fork->lsize) {
492                         fork->lsize = pos;
493                 }
494                 entry->modify_date = hfs_u_to_mtime(CURRENT_TIME);
495                 hfs_cat_mark_dirty(entry);
496         }
497         return written;
498 }
499
500 /*
501  * hfs_file_fix_mode()
502  *
503  * Fixes up the permissions on a file after changing the write-inhibit bit.
504  */
505 void hfs_file_fix_mode(struct hfs_cat_entry *entry)
506 {
507         struct dentry **de = entry->sys_entry;
508         int i;
509
510         if (entry->u.file.flags & HFS_FIL_LOCK) {
511                 for (i = 0; i < 4; ++i) {
512                         if (de[i]) {
513                                 de[i]->d_inode->i_mode &= ~S_IWUGO;
514                         }
515                 }
516         } else {
517                 for (i = 0; i < 4; ++i) {
518                         if (de[i]) {
519                                 struct inode *inode = de[i]->d_inode;
520                                 inode->i_mode |= S_IWUGO;
521                                 inode->i_mode &= 
522                                   ~HFS_SB(inode->i_sb)->s_umask;
523                         }
524                 }
525         }
526 }