]>
Commit | Line | Data |
---|---|---|
1da177e4 | 1 | /* |
f25dfb5e | 2 | * file.c - NTFS kernel file operations. Part of the Linux-NTFS project. |
1da177e4 | 3 | * |
f25dfb5e | 4 | * Copyright (c) 2001-2005 Anton Altaparmakov |
1da177e4 LT |
5 | * |
6 | * This program/include file is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU General Public License as published | |
8 | * by the Free Software Foundation; either version 2 of the License, or | |
9 | * (at your option) any later version. | |
10 | * | |
11 | * This program/include file is distributed in the hope that it will be | |
12 | * useful, but WITHOUT ANY WARRANTY; without even the implied warranty | |
13 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | * GNU General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * along with this program (in the main directory of the Linux-NTFS | |
18 | * distribution in the file COPYING); if not, write to the Free Software | |
19 | * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
20 | */ | |
21 | ||
22 | #include <linux/pagemap.h> | |
23 | #include <linux/buffer_head.h> | |
24 | ||
25 | #include "inode.h" | |
26 | #include "debug.h" | |
27 | #include "ntfs.h" | |
28 | ||
29 | /** | |
30 | * ntfs_file_open - called when an inode is about to be opened | |
31 | * @vi: inode to be opened | |
32 | * @filp: file structure describing the inode | |
33 | * | |
34 | * Limit file size to the page cache limit on architectures where unsigned long | |
35 | * is 32-bits. This is the most we can do for now without overflowing the page | |
36 | * cache page index. Doing it this way means we don't run into problems because | |
37 | * of existing too large files. It would be better to allow the user to read | |
38 | * the beginning of the file but I doubt very much anyone is going to hit this | |
39 | * check on a 32-bit architecture, so there is no point in adding the extra | |
40 | * complexity required to support this. | |
41 | * | |
42 | * On 64-bit architectures, the check is hopefully optimized away by the | |
43 | * compiler. | |
44 | * | |
45 | * After the check passes, just call generic_file_open() to do its work. | |
46 | */ | |
47 | static int ntfs_file_open(struct inode *vi, struct file *filp) | |
48 | { | |
49 | if (sizeof(unsigned long) < 8) { | |
d4b9ba7b | 50 | if (i_size_read(vi) > MAX_LFS_FILESIZE) |
1da177e4 LT |
51 | return -EFBIG; |
52 | } | |
53 | return generic_file_open(vi, filp); | |
54 | } | |
55 | ||
56 | #ifdef NTFS_RW | |
57 | ||
58 | /** | |
59 | * ntfs_file_fsync - sync a file to disk | |
60 | * @filp: file to be synced | |
61 | * @dentry: dentry describing the file to sync | |
62 | * @datasync: if non-zero only flush user data and not metadata | |
63 | * | |
64 | * Data integrity sync of a file to disk. Used for fsync, fdatasync, and msync | |
65 | * system calls. This function is inspired by fs/buffer.c::file_fsync(). | |
66 | * | |
67 | * If @datasync is false, write the mft record and all associated extent mft | |
68 | * records as well as the $DATA attribute and then sync the block device. | |
69 | * | |
70 | * If @datasync is true and the attribute is non-resident, we skip the writing | |
71 | * of the mft record and all associated extent mft records (this might still | |
72 | * happen due to the write_inode_now() call). | |
73 | * | |
74 | * Also, if @datasync is true, we do not wait on the inode to be written out | |
75 | * but we always wait on the page cache pages to be written out. | |
76 | * | |
77 | * Note: In the past @filp could be NULL so we ignore it as we don't need it | |
78 | * anyway. | |
79 | * | |
80 | * Locking: Caller must hold i_sem on the inode. | |
81 | * | |
82 | * TODO: We should probably also write all attribute/index inodes associated | |
83 | * with this inode but since we have no simple way of getting to them we ignore | |
84 | * this problem for now. | |
85 | */ | |
86 | static int ntfs_file_fsync(struct file *filp, struct dentry *dentry, | |
87 | int datasync) | |
88 | { | |
89 | struct inode *vi = dentry->d_inode; | |
90 | int err, ret = 0; | |
91 | ||
92 | ntfs_debug("Entering for inode 0x%lx.", vi->i_ino); | |
93 | BUG_ON(S_ISDIR(vi->i_mode)); | |
94 | if (!datasync || !NInoNonResident(NTFS_I(vi))) | |
95 | ret = ntfs_write_inode(vi, 1); | |
96 | write_inode_now(vi, !datasync); | |
f25dfb5e AA |
97 | /* |
98 | * NOTE: If we were to use mapping->private_list (see ext2 and | |
99 | * fs/buffer.c) for dirty blocks then we could optimize the below to be | |
100 | * sync_mapping_buffers(vi->i_mapping). | |
101 | */ | |
1da177e4 LT |
102 | err = sync_blockdev(vi->i_sb->s_bdev); |
103 | if (unlikely(err && !ret)) | |
104 | ret = err; | |
105 | if (likely(!ret)) | |
106 | ntfs_debug("Done."); | |
107 | else | |
108 | ntfs_warning(vi->i_sb, "Failed to f%ssync inode 0x%lx. Error " | |
109 | "%u.", datasync ? "data" : "", vi->i_ino, -ret); | |
110 | return ret; | |
111 | } | |
112 | ||
113 | #endif /* NTFS_RW */ | |
114 | ||
115 | struct file_operations ntfs_file_ops = { | |
116 | .llseek = generic_file_llseek, /* Seek inside file. */ | |
117 | .read = generic_file_read, /* Read from file. */ | |
118 | .aio_read = generic_file_aio_read, /* Async read from file. */ | |
119 | .readv = generic_file_readv, /* Read from file. */ | |
120 | #ifdef NTFS_RW | |
121 | .write = generic_file_write, /* Write to file. */ | |
122 | .aio_write = generic_file_aio_write, /* Async write to file. */ | |
123 | .writev = generic_file_writev, /* Write to file. */ | |
124 | /*.release = ,*/ /* Last file is closed. See | |
125 | fs/ext2/file.c:: | |
126 | ext2_release_file() for | |
127 | how to use this to discard | |
128 | preallocated space for | |
129 | write opened files. */ | |
130 | .fsync = ntfs_file_fsync, /* Sync a file to disk. */ | |
131 | /*.aio_fsync = ,*/ /* Sync all outstanding async | |
132 | i/o operations on a | |
133 | kiocb. */ | |
134 | #endif /* NTFS_RW */ | |
135 | /*.ioctl = ,*/ /* Perform function on the | |
136 | mounted filesystem. */ | |
137 | .mmap = generic_file_mmap, /* Mmap file. */ | |
138 | .open = ntfs_file_open, /* Open file. */ | |
139 | .sendfile = generic_file_sendfile, /* Zero-copy data send with | |
140 | the data source being on | |
141 | the ntfs partition. We | |
142 | do not need to care about | |
143 | the data destination. */ | |
144 | /*.sendpage = ,*/ /* Zero-copy data send with | |
145 | the data destination being | |
146 | on the ntfs partition. We | |
147 | do not need to care about | |
148 | the data source. */ | |
149 | }; | |
150 | ||
151 | struct inode_operations ntfs_file_inode_ops = { | |
152 | #ifdef NTFS_RW | |
153 | .truncate = ntfs_truncate_vfs, | |
154 | .setattr = ntfs_setattr, | |
155 | #endif /* NTFS_RW */ | |
156 | }; | |
157 | ||
158 | struct file_operations ntfs_empty_file_ops = {}; | |
159 | ||
160 | struct inode_operations ntfs_empty_inode_ops = {}; |