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  */
hfs_getblk(struct hfs_fork * fork,int block,int create)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  */
hfs_get_block(struct inode * inode,long iblock,struct buffer_head * bh_result,int create)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.  */
hfs_file_read(struct file * filp,char * buf,hfs_rwarg_t count,loff_t * ppos)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  */
hfs_file_write(struct file * filp,const char * buf,hfs_rwarg_t count,loff_t * ppos)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  */
hfs_file_truncate(struct inode * inode)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  */
xlate_to_user(char * buf,const char * data,int count)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  */
xlate_from_user(char * data,const char * buf,int count)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  */
hfs_do_read(struct inode * inode,struct hfs_fork * fork,hfs_u32 pos,char * buf,hfs_u32 count,int reada)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  */
hfs_do_write(struct inode * inode,struct hfs_fork * fork,hfs_u32 pos,const char * buf,hfs_u32 count)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  */
hfs_file_fix_mode(struct hfs_cat_entry * entry)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 }
535