Blame view

fs/hpfs/file.c 5.71 KB
b24413180   Greg Kroah-Hartman   License cleanup: ...
1
  // SPDX-License-Identifier: GPL-2.0
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
2
3
4
5
6
7
8
9
10
  /*
   *  linux/fs/hpfs/file.c
   *
   *  Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
   *
   *  file VFS functions
   */
  
  #include "hpfs_fn.h"
a0c1b7596   Mikulas Patocka   hpfs: use mpage
11
  #include <linux/mpage.h>
10c5db286   Christoph Hellwig   fs: move the fiem...
12
  #include <linux/fiemap.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
13
14
15
16
17
  
  #define BLOCKS(size) (((size) + 511) >> 9)
  
  static int hpfs_file_release(struct inode *inode, struct file *file)
  {
9a311b96c   Arnd Bergmann   hpfs: remove the BKL
18
  	hpfs_lock(inode->i_sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
19
  	hpfs_write_if_changed(inode);
9a311b96c   Arnd Bergmann   hpfs: remove the BKL
20
  	hpfs_unlock(inode->i_sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
21
22
  	return 0;
  }
02c24a821   Josef Bacik   fs: push i_mutex ...
23
  int hpfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
24
  {
bc8728ee5   Mikulas Patocka   HPFS: Implement f...
25
  	struct inode *inode = file->f_mapping->host;
02c24a821   Josef Bacik   fs: push i_mutex ...
26
  	int ret;
3b49c9a1e   Jeff Layton   fs: convert a pil...
27
  	ret = file_write_and_wait_range(file, start, end);
02c24a821   Josef Bacik   fs: push i_mutex ...
28
29
  	if (ret)
  		return ret;
bc8728ee5   Mikulas Patocka   HPFS: Implement f...
30
  	return sync_blockdev(inode->i_sb->s_bdev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
31
32
33
34
35
36
  }
  
  /*
   * generic_file_read often calls bmap with non-existing sector,
   * so we must ignore such errors.
   */
a0c1b7596   Mikulas Patocka   hpfs: use mpage
37
  static secno hpfs_bmap(struct inode *inode, unsigned file_secno, unsigned *n_secs)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
38
39
40
41
42
43
44
  {
  	struct hpfs_inode_info *hpfs_inode = hpfs_i(inode);
  	unsigned n, disk_secno;
  	struct fnode *fnode;
  	struct buffer_head *bh;
  	if (BLOCKS(hpfs_i(inode)->mmu_private) <= file_secno) return 0;
  	n = file_secno - hpfs_inode->i_file_sec;
a0c1b7596   Mikulas Patocka   hpfs: use mpage
45
46
47
48
  	if (n < hpfs_inode->i_n_secs) {
  		*n_secs = hpfs_inode->i_n_secs - n;
  		return hpfs_inode->i_disk_sec + n;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49
50
51
52
  	if (!(fnode = hpfs_map_fnode(inode->i_sb, inode->i_ino, &bh))) return 0;
  	disk_secno = hpfs_bplus_lookup(inode->i_sb, inode, &fnode->btree, file_secno, bh);
  	if (disk_secno == -1) return 0;
  	if (hpfs_chk_sectors(inode->i_sb, disk_secno, 1, "bmap")) return 0;
a0c1b7596   Mikulas Patocka   hpfs: use mpage
53
54
55
56
57
58
  	n = file_secno - hpfs_inode->i_file_sec;
  	if (n < hpfs_inode->i_n_secs) {
  		*n_secs = hpfs_inode->i_n_secs - n;
  		return hpfs_inode->i_disk_sec + n;
  	}
  	*n_secs = 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
59
60
  	return disk_secno;
  }
70b31c4c8   Marco Stornelli   hpfs: drop vmtrun...
61
  void hpfs_truncate(struct inode *i)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
62
63
  {
  	if (IS_IMMUTABLE(i)) return /*-EPERM*/;
7dd29d8d8   Mikulas Patocka   HPFS: Introduce a...
64
  	hpfs_lock_assert(i->i_sb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
65
66
67
68
69
70
  	hpfs_i(i)->i_n_secs = 0;
  	i->i_blocks = 1 + ((i->i_size + 511) >> 9);
  	hpfs_i(i)->mmu_private = i->i_size;
  	hpfs_truncate_btree(i->i_sb, i->i_ino, 1, ((i->i_size + 511) >> 9));
  	hpfs_write_inode(i);
  	hpfs_i(i)->i_n_secs = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
71
72
73
74
  }
  
  static int hpfs_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create)
  {
7dd29d8d8   Mikulas Patocka   HPFS: Introduce a...
75
  	int r;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
76
  	secno s;
a0c1b7596   Mikulas Patocka   hpfs: use mpage
77
  	unsigned n_secs;
7dd29d8d8   Mikulas Patocka   HPFS: Introduce a...
78
  	hpfs_lock(inode->i_sb);
a0c1b7596   Mikulas Patocka   hpfs: use mpage
79
  	s = hpfs_bmap(inode, iblock, &n_secs);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
80
  	if (s) {
a0c1b7596   Mikulas Patocka   hpfs: use mpage
81
82
  		if (bh_result->b_size >> 9 < n_secs)
  			n_secs = bh_result->b_size >> 9;
a64eefaac   Mikulas Patocka   hpfs: support hot...
83
84
85
86
87
  		n_secs = hpfs_search_hotfix_map_for_range(inode->i_sb, s, n_secs);
  		if (unlikely(!n_secs)) {
  			s = hpfs_search_hotfix_map(inode->i_sb, s);
  			n_secs = 1;
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
88
  		map_bh(bh_result, inode->i_sb, s);
a0c1b7596   Mikulas Patocka   hpfs: use mpage
89
  		bh_result->b_size = n_secs << 9;
7dd29d8d8   Mikulas Patocka   HPFS: Introduce a...
90
  		goto ret_0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
91
  	}
7dd29d8d8   Mikulas Patocka   HPFS: Introduce a...
92
  	if (!create) goto ret_0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
93
94
  	if (iblock<<9 != hpfs_i(inode)->mmu_private) {
  		BUG();
7dd29d8d8   Mikulas Patocka   HPFS: Introduce a...
95
96
  		r = -EIO;
  		goto ret_r;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
97
98
99
  	}
  	if ((s = hpfs_add_sector_to_btree(inode->i_sb, inode->i_ino, 1, inode->i_blocks - 1)) == -1) {
  		hpfs_truncate_btree(inode->i_sb, inode->i_ino, 1, inode->i_blocks - 1);
7dd29d8d8   Mikulas Patocka   HPFS: Introduce a...
100
101
  		r = -ENOSPC;
  		goto ret_r;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
102
103
104
105
  	}
  	inode->i_blocks++;
  	hpfs_i(inode)->mmu_private += 512;
  	set_buffer_new(bh_result);
a64eefaac   Mikulas Patocka   hpfs: support hot...
106
  	map_bh(bh_result, inode->i_sb, hpfs_search_hotfix_map(inode->i_sb, s));
7dd29d8d8   Mikulas Patocka   HPFS: Introduce a...
107
108
109
110
111
  	ret_0:
  	r = 0;
  	ret_r:
  	hpfs_unlock(inode->i_sb);
  	return r;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
112
  }
a0c1b7596   Mikulas Patocka   hpfs: use mpage
113
114
115
116
  static int hpfs_readpage(struct file *file, struct page *page)
  {
  	return mpage_readpage(page, hpfs_get_block);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
117
118
  static int hpfs_writepage(struct page *page, struct writeback_control *wbc)
  {
a0c1b7596   Mikulas Patocka   hpfs: use mpage
119
  	return block_write_full_page(page, hpfs_get_block, wbc);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
120
  }
d6091b720   Nick Piggin   hpfs: convert to ...
121

d4388340a   Matthew Wilcox (Oracle)   fs: convert mpage...
122
  static void hpfs_readahead(struct readahead_control *rac)
a0c1b7596   Mikulas Patocka   hpfs: use mpage
123
  {
d4388340a   Matthew Wilcox (Oracle)   fs: convert mpage...
124
  	mpage_readahead(rac, hpfs_get_block);
a0c1b7596   Mikulas Patocka   hpfs: use mpage
125
126
127
128
  }
  
  static int hpfs_writepages(struct address_space *mapping,
  			   struct writeback_control *wbc)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
129
  {
a0c1b7596   Mikulas Patocka   hpfs: use mpage
130
  	return mpage_writepages(mapping, wbc, hpfs_get_block);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
131
  }
d6091b720   Nick Piggin   hpfs: convert to ...
132

70b31c4c8   Marco Stornelli   hpfs: drop vmtrun...
133
134
135
  static void hpfs_write_failed(struct address_space *mapping, loff_t to)
  {
  	struct inode *inode = mapping->host;
bbd465df7   Mikulas Patocka   hpfs: fix warning...
136
  	hpfs_lock(inode->i_sb);
70b31c4c8   Marco Stornelli   hpfs: drop vmtrun...
137
  	if (to > inode->i_size) {
7caef2676   Kirill A. Shutemov   truncate: drop 'o...
138
  		truncate_pagecache(inode, inode->i_size);
70b31c4c8   Marco Stornelli   hpfs: drop vmtrun...
139
140
  		hpfs_truncate(inode);
  	}
bbd465df7   Mikulas Patocka   hpfs: fix warning...
141
142
  
  	hpfs_unlock(inode->i_sb);
70b31c4c8   Marco Stornelli   hpfs: drop vmtrun...
143
  }
d6091b720   Nick Piggin   hpfs: convert to ...
144
145
146
  static int hpfs_write_begin(struct file *file, struct address_space *mapping,
  			loff_t pos, unsigned len, unsigned flags,
  			struct page **pagep, void **fsdata)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
147
  {
282dc1788   Christoph Hellwig   get rid of cont_w...
148
  	int ret;
d6091b720   Nick Piggin   hpfs: convert to ...
149
  	*pagep = NULL;
282dc1788   Christoph Hellwig   get rid of cont_w...
150
  	ret = cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
d6091b720   Nick Piggin   hpfs: convert to ...
151
152
  				hpfs_get_block,
  				&hpfs_i(mapping->host)->mmu_private);
70b31c4c8   Marco Stornelli   hpfs: drop vmtrun...
153
154
  	if (unlikely(ret))
  		hpfs_write_failed(mapping, pos + len);
282dc1788   Christoph Hellwig   get rid of cont_w...
155
156
  
  	return ret;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
157
  }
d6091b720   Nick Piggin   hpfs: convert to ...
158

5f2e354f5   Al Viro   hpfs: move settin...
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
  static int hpfs_write_end(struct file *file, struct address_space *mapping,
  			loff_t pos, unsigned len, unsigned copied,
  			struct page *pagep, void *fsdata)
  {
  	struct inode *inode = mapping->host;
  	int err;
  	err = generic_write_end(file, mapping, pos, len, copied, pagep, fsdata);
  	if (err < len)
  		hpfs_write_failed(mapping, pos + len);
  	if (!(err < 0)) {
  		/* make sure we write it on close, if not earlier */
  		hpfs_lock(inode->i_sb);
  		hpfs_i(inode)->i_dirty = 1;
  		hpfs_unlock(inode->i_sb);
  	}
  	return err;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
176
177
  static sector_t _hpfs_bmap(struct address_space *mapping, sector_t block)
  {
a64eefaac   Mikulas Patocka   hpfs: support hot...
178
  	return generic_block_bmap(mapping, block, hpfs_get_block);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
179
  }
d6091b720   Nick Piggin   hpfs: convert to ...
180

91fff9b34   Mikulas Patocka   hpfs: support FIEMAP
181
182
183
184
  static int hpfs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, u64 start, u64 len)
  {
  	return generic_block_fiemap(inode, fieinfo, start, len, hpfs_get_block);
  }
f5e54d6e5   Christoph Hellwig   [PATCH] mark addr...
185
  const struct address_space_operations hpfs_aops = {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
186
187
  	.readpage = hpfs_readpage,
  	.writepage = hpfs_writepage,
d4388340a   Matthew Wilcox (Oracle)   fs: convert mpage...
188
  	.readahead = hpfs_readahead,
a0c1b7596   Mikulas Patocka   hpfs: use mpage
189
  	.writepages = hpfs_writepages,
d6091b720   Nick Piggin   hpfs: convert to ...
190
  	.write_begin = hpfs_write_begin,
5f2e354f5   Al Viro   hpfs: move settin...
191
  	.write_end = hpfs_write_end,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
192
193
  	.bmap = _hpfs_bmap
  };
4b6f5d20b   Arjan van de Ven   [PATCH] Make most...
194
  const struct file_operations hpfs_file_ops =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
195
196
  {
  	.llseek		= generic_file_llseek,
aad4f8bb4   Al Viro   switch simple gen...
197
  	.read_iter	= generic_file_read_iter,
8174202b3   Al Viro   write_iter varian...
198
  	.write_iter	= generic_file_write_iter,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
199
200
201
  	.mmap		= generic_file_mmap,
  	.release	= hpfs_file_release,
  	.fsync		= hpfs_file_fsync,
5ffc4ef45   Jens Axboe   sendfile: remove ...
202
  	.splice_read	= generic_file_splice_read,
a27b5b97d   Mikulas Patocka   hpfs: add fstrim ...
203
  	.unlocked_ioctl	= hpfs_ioctl,
314999dcb   Arnd Bergmann   fs: compat_ioctl:...
204
  	.compat_ioctl	= compat_ptr_ioctl,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
205
  };
92e1d5be9   Arjan van de Ven   [PATCH] mark stru...
206
  const struct inode_operations hpfs_file_iops =
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
207
  {
ca30bc995   Christoph Hellwig   [PATCH] hpfs: cle...
208
  	.setattr	= hpfs_setattr,
91fff9b34   Mikulas Patocka   hpfs: support FIEMAP
209
  	.fiemap		= hpfs_fiemap,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
210
  };