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