History

fs: introduce new truncate sequence

Introduce a new truncate calling sequence into fs/mm subsystems. Rather than setattr > vmtruncate > truncate, have filesystems call their truncate sequence from ->setattr if filesystem specific operations are required. vmtruncate is deprecated, and truncate_pagecache and inode_newsize_ok helpers introduced previously should be used. simple_setattr is introduced for simple in-ram filesystems to implement the new truncate sequence. Eventually all filesystems should be converted to implement a setattr, and the default code in notify_change should go away. simple_setsize is also introduced to perform just the ATTR_SIZE portion of simple_setattr (ie. changing i_size and trimming pagecache). To implement the new truncate sequence: - filesystem specific manipulations (eg freeing blocks) must be done in the setattr method rather than ->truncate. - vmtruncate can not be used by core code to trim blocks past i_size in the event of write failure after allocation, so this must be performed in the fs code. - convert usage of helpers block_write_begin, nobh_write_begin, cont_write_begin, and *blockdev_direct_IO* to use _newtrunc postfixed variants. These avoid calling vmtruncate to trim blocks (see previous). - inode_setattr should not be used. generic_setattr is a new function to be used to copy simple attributes into the generic inode. - make use of the better opportunity to handle errors with the new sequence. Big problem with the previous calling sequence: the filesystem is not called until i_size has already changed. This means it is not allowed to fail the call, and also it does not know what the previous i_size was. Also, generic code calling vmtruncate to truncate allocated blocks in case of error had no good way to return a meaningful error (or, for example, atomically handle block deallocation).

npiggin@suse.de committed 16 years ago

Commit 7bb46a61 parent 7000d3c8 files · +300 −63Browse files

Unified · Split

8 files
  1. Documentation/filesystems/vfs.txt +6 −1
  2. fs/attr.c +40 −10
  3. fs/buffer.c +98 −25
  4. fs/direct-io.c +40 −21
  5. fs/libfs.c +76 −0
  6. include/linux/buffer_head.h +9 −0
  7. include/linux/fs.h +26 −1
  8. mm/truncate.c +5 −5
Documentation/filesystems/vfs.txt+6−1
@@ -401,11 +401,16 @@ otherwise noted. · 400 unmodified lines
401401 started might not be in the page cache at the end of the
402402 walk).
403403
404− truncate: called by the VFS to change the size of a file. The
404+ truncate: Deprecated. This will not be called if ->setsize is defined.
405+ Called by the VFS to change the size of a file. The
405406 i_size field of the inode is set to the desired size by the
406407 VFS before this method is called. This method is called by
407408 the truncate(2) system call and related functionality.
408409
410+ Note: ->truncate and vmtruncate are deprecated. Do not add new
411+ instances/calls of these. Filesystems should be converted to do their
412+ truncate sequence via ->setattr().
413+
409414 permission: called by the VFS to check for access rights on a POSIX-like
410415 filesystem.
411416
fs/attr.c+40−10
@@ -67,14 +67,14 @@ EXPORT_SYMBOL(inode_change_ok); · 66 unmodified lines
6767 * @offset: the new size to assign to the inode
6868 * @Returns: 0 on success, -ve errno on failure
6969 *
70+ * inode_newsize_ok must be called with i_mutex held.
71+ *
7072 * inode_newsize_ok will check filesystem limits and ulimits to check that the
7173 * new inode size is within limits. inode_newsize_ok will also send SIGXFSZ
7274 * when necessary. Caller must not proceed with inode size change if failure is
7375 * returned. @inode must be a file (not directory), with appropriate
7476 * permissions to allow truncate (inode_newsize_ok does NOT check these
7577 * conditions).
76− *
77− * inode_newsize_ok must be called with i_mutex held.
7878 */
7979 int inode_newsize_ok(const struct inode *inode, loff_t offset)
8080 {
@@ -104,17 +104,25 @@ out_big: · 23 unmodified lines
104104 }
105105 EXPORT_SYMBOL(inode_newsize_ok);
106106
107−int inode_setattr(struct inode * inode, struct iattr * attr)
107+/**
108+ * generic_setattr - copy simple metadata updates into the generic inode
109+ * @inode: the inode to be updated
110+ * @attr: the new attributes
111+ *
112+ * generic_setattr must be called with i_mutex held.
113+ *
114+ * generic_setattr updates the inode's metadata with that specified
115+ * in attr. Noticably missing is inode size update, which is more complex
116+ * as it requires pagecache updates. See simple_setsize.
117+ *
118+ * The inode is not marked as dirty after this operation. The rationale is
119+ * that for "simple" filesystems, the struct inode is the inode storage.
120+ * The caller is free to mark the inode dirty afterwards if needed.
121+ */
122+void generic_setattr(struct inode *inode, const struct iattr *attr)
108123 {
109124 unsigned int ia_valid = attr->ia_valid;
110125
111− if (ia_valid & ATTR_SIZE &&
112− attr->ia_size != i_size_read(inode)) {
113− int error = vmtruncate(inode, attr->ia_size);
114− if (error)
115− return error;
116− }
117−
118126 if (ia_valid & ATTR_UID)
119127 inode->i_uid = attr->ia_uid;
120128 if (ia_valid & ATTR_GID)
@@ -135,6 +143,28 @@ int inode_setattr(struct inode * inode, struct iattr * attr) · 14 unmodified lines
135143 mode &= ~S_ISGID;
136144 inode->i_mode = mode;
137145 }
146+}
147+EXPORT_SYMBOL(generic_setattr);
148+
149+/*
150+ * note this function is deprecated, the new truncate sequence should be
151+ * used instead -- see eg. simple_setsize, generic_setattr.
152+ */
153+int inode_setattr(struct inode *inode, const struct iattr *attr)
154+{
155+ unsigned int ia_valid = attr->ia_valid;
156+
157+ if (ia_valid & ATTR_SIZE &&
158+ attr->ia_size != i_size_read(inode)) {
159+ int error;
160+
161+ error = vmtruncate(inode, attr->ia_size);
162+ if (error)
163+ return error;
164+ }
165+
166+ generic_setattr(inode, attr);
167+
138168 mark_inode_dirty(inode);
139169
140170 return 0;
fs/buffer.c+98−25
@@ -1949,14 +1949,11 @@ static int __block_commit_write(struct inode *inode, struct page *page, · 1948 unmodified lines
19491949 }
19501950
19511951 /*
1952− * block_write_begin takes care of the basic task of block allocation and
1953− * bringing partial write blocks uptodate first.
1954− *
1955− * If *pagep is not NULL, then block_write_begin uses the locked page
1956− * at *pagep rather than allocating its own. In this case, the page will
1957− * not be unlocked or deallocated on failure.
1952+ * Filesystems implementing the new truncate sequence should use the
1953+ * _newtrunc postfix variant which won't incorrectly call vmtruncate.
1954+ * The filesystem needs to handle block truncation upon failure.
19581955 */
1959−int block_write_begin(struct file *file, struct address_space *mapping,
1956+int block_write_begin_newtrunc(struct file *file, struct address_space *mapping,
19601957 loff_t pos, unsigned len, unsigned flags,
19611958 struct page **pagep, void **fsdata,
19621959 get_block_t *get_block)
@@ -1992,20 +1989,50 @@ int block_write_begin(struct file *file, struct address_space *mapping, · 29 unmodified lines
19921989 unlock_page(page);
19931990 page_cache_release(page);
19941991 *pagep = NULL;
1995−
1996− /*
1997− * prepare_write() may have instantiated a few blocks
1998− * outside i_size. Trim these off again. Don't need
1999− * i_size_read because we hold i_mutex.
2000− */
2001− if (pos + len > inode->i_size)
2002− vmtruncate(inode, inode->i_size);
20031992 }
20041993 }
20051994
20061995 out:
20071996 return status;
20081997 }
1998+EXPORT_SYMBOL(block_write_begin_newtrunc);
1999+
2000+/*
2001+ * block_write_begin takes care of the basic task of block allocation and
2002+ * bringing partial write blocks uptodate first.
2003+ *
2004+ * If *pagep is not NULL, then block_write_begin uses the locked page
2005+ * at *pagep rather than allocating its own. In this case, the page will
2006+ * not be unlocked or deallocated on failure.
2007+ */
2008+int block_write_begin(struct file *file, struct address_space *mapping,
2009+ loff_t pos, unsigned len, unsigned flags,
2010+ struct page **pagep, void **fsdata,
2011+ get_block_t *get_block)
2012+{
2013+ int ret;
2014+
2015+ ret = block_write_begin_newtrunc(file, mapping, pos, len, flags,
2016+ pagep, fsdata, get_block);
2017+
2018+ /*
2019+ * prepare_write() may have instantiated a few blocks
2020+ * outside i_size. Trim these off again. Don't need
2021+ * i_size_read because we hold i_mutex.
2022+ *
2023+ * Filesystems which pass down their own page also cannot
2024+ * call into vmtruncate here because it would lead to lock
2025+ * inversion problems (*pagep is locked). This is a further
2026+ * example of where the old truncate sequence is inadequate.
2027+ */
2028+ if (unlikely(ret) && *pagep == NULL) {
2029+ loff_t isize = mapping->host->i_size;
2030+ if (pos + len > isize)
2031+ vmtruncate(mapping->host, isize);
2032+ }
2033+
2034+ return ret;
2035+}
20092036 EXPORT_SYMBOL(block_write_begin);
20102037
20112038 int block_write_end(struct file *file, struct address_space *mapping,
@@ -2324,7 +2351,7 @@ out: · 312 unmodified lines
23242351 * For moronic filesystems that do not allow holes in file.
23252352 * We may have to extend the file.
23262353 */
2327−int cont_write_begin(struct file *file, struct address_space *mapping,
2354+int cont_write_begin_newtrunc(struct file *file, struct address_space *mapping,
23282355 loff_t pos, unsigned len, unsigned flags,
23292356 struct page **pagep, void **fsdata,
23302357 get_block_t *get_block, loff_t *bytes)
@@ -2345,11 +2372,30 @@ int cont_write_begin(struct file *file, struct address_space *mapping, · 14 unmodified lines
23452372 }
23462373
23472374 *pagep = NULL;
2348− err = block_write_begin(file, mapping, pos, len,
2375+ err = block_write_begin_newtrunc(file, mapping, pos, len,
23492376 flags, pagep, fsdata, get_block);
23502377 out:
23512378 return err;
23522379 }
2380+EXPORT_SYMBOL(cont_write_begin_newtrunc);
2381+
2382+int cont_write_begin(struct file *file, struct address_space *mapping,
2383+ loff_t pos, unsigned len, unsigned flags,
2384+ struct page **pagep, void **fsdata,
2385+ get_block_t *get_block, loff_t *bytes)
2386+{
2387+ int ret;
2388+
2389+ ret = cont_write_begin_newtrunc(file, mapping, pos, len, flags,
2390+ pagep, fsdata, get_block, bytes);
2391+ if (unlikely(ret)) {
2392+ loff_t isize = mapping->host->i_size;
2393+ if (pos + len > isize)
2394+ vmtruncate(mapping->host, isize);
2395+ }
2396+
2397+ return ret;
2398+}
23532399 EXPORT_SYMBOL(cont_write_begin);
23542400
23552401 int block_prepare_write(struct page *page, unsigned from, unsigned to,
@@ -2381,7 +2427,7 @@ EXPORT_SYMBOL(block_commit_write); · 25 unmodified lines
23812427 *
23822428 * We are not allowed to take the i_mutex here so we have to play games to
23832429 * protect against truncate races as the page could now be beyond EOF. Because
2384− * vmtruncate() writes the inode size before removing pages, once we have the
2430+ * truncate writes the inode size before removing pages, once we have the
23852431 * page lock we can determine safely if the page is beyond EOF. If it is not
23862432 * beyond EOF, then the page is guaranteed safe against truncation until we
23872433 * unlock the page.
@@ -2464,10 +2510,11 @@ static void attach_nobh_buffers(struct page *page, struct buffer_head *head) · 76 unmodified lines
24642510 }
24652511
24662512 /*
2467− * On entry, the page is fully not uptodate.
2468− * On exit the page is fully uptodate in the areas outside (from,to)
2513+ * Filesystems implementing the new truncate sequence should use the
2514+ * _newtrunc postfix variant which won't incorrectly call vmtruncate.
2515+ * The filesystem needs to handle block truncation upon failure.
24692516 */
2470−int nobh_write_begin(struct file *file, struct address_space *mapping,
2517+int nobh_write_begin_newtrunc(struct file *file, struct address_space *mapping,
24712518 loff_t pos, unsigned len, unsigned flags,
24722519 struct page **pagep, void **fsdata,
24732520 get_block_t *get_block)
@@ -2500,8 +2547,8 @@ int nobh_write_begin(struct file *file, struct address_space *mapping, · 26 unmodified lines
25002547 unlock_page(page);
25012548 page_cache_release(page);
25022549 *pagep = NULL;
2503− return block_write_begin(file, mapping, pos, len, flags, pagep,
2504− fsdata, get_block);
2550+ return block_write_begin_newtrunc(file, mapping, pos, len,
2551+ flags, pagep, fsdata, get_block);
25052552 }
25062553
25072554 if (PageMappedToDisk(page))
@@ -2605,8 +2652,34 @@ out_release: · 97 unmodified lines
26052652 page_cache_release(page);
26062653 *pagep = NULL;
26072654
2608− if (pos + len > inode->i_size)
2609− vmtruncate(inode, inode->i_size);
2655+ return ret;
2656+}
2657+EXPORT_SYMBOL(nobh_write_begin_newtrunc);
2658+
2659+/*
2660+ * On entry, the page is fully not uptodate.
2661+ * On exit the page is fully uptodate in the areas outside (from,to)
2662+ */
2663+int nobh_write_begin(struct file *file, struct address_space *mapping,
2664+ loff_t pos, unsigned len, unsigned flags,
2665+ struct page **pagep, void **fsdata,
2666+ get_block_t *get_block)
2667+{
2668+ int ret;
2669+
2670+ ret = nobh_write_begin_newtrunc(file, mapping, pos, len, flags,
2671+ pagep, fsdata, get_block);
2672+
2673+ /*
2674+ * prepare_write() may have instantiated a few blocks
2675+ * outside i_size. Trim these off again. Don't need
2676+ * i_size_read because we hold i_mutex.
2677+ */
2678+ if (unlikely(ret)) {
2679+ loff_t isize = mapping->host->i_size;
2680+ if (pos + len > isize)
2681+ vmtruncate(mapping->host, isize);
2682+ }
26102683
26112684 return ret;
26122685 }
fs/direct-io.c+40−21
@@ -1134,27 +1134,8 @@ direct_io_worker(int rw, struct kiocb *iocb, struct inode *inode, · 1133 unmodified lines
11341134 return ret;
11351135 }
11361136
1137−/*
1138− * This is a library function for use by filesystem drivers.
1139− *
1140− * The locking rules are governed by the flags parameter:
1141− * - if the flags value contains DIO_LOCKING we use a fancy locking
1142− * scheme for dumb filesystems.
1143− * For writes this function is called under i_mutex and returns with
1144− * i_mutex held, for reads, i_mutex is not held on entry, but it is
1145− * taken and dropped again before returning.
1146− * For reads and writes i_alloc_sem is taken in shared mode and released
1147− * on I/O completion (which may happen asynchronously after returning to
1148− * the caller).
1149− *
1150− * - if the flags value does NOT contain DIO_LOCKING we don't use any
1151− * internal locking but rather rely on the filesystem to synchronize
1152− * direct I/O reads/writes versus each other and truncate.
1153− * For reads and writes both i_mutex and i_alloc_sem are not held on
1154− * entry and are never taken.
1155− */
11561137 ssize_t
1157−__blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
1138+__blockdev_direct_IO_newtrunc(int rw, struct kiocb *iocb, struct inode *inode,
11581139 struct block_device *bdev, const struct iovec *iov, loff_t offset,
11591140 unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
11601141 dio_submit_t submit_io, int flags)
@@ -1247,9 +1228,46 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, · 86 unmodified lines
12471228 nr_segs, blkbits, get_block, end_io,
12481229 submit_io, dio);
12491230
1231+out:
1232+ return retval;
1233+}
1234+EXPORT_SYMBOL(__blockdev_direct_IO_newtrunc);
1235+
1236+/*
1237+ * This is a library function for use by filesystem drivers.
1238+ *
1239+ * The locking rules are governed by the flags parameter:
1240+ * - if the flags value contains DIO_LOCKING we use a fancy locking
1241+ * scheme for dumb filesystems.
1242+ * For writes this function is called under i_mutex and returns with
1243+ * i_mutex held, for reads, i_mutex is not held on entry, but it is
1244+ * taken and dropped again before returning.
1245+ * For reads and writes i_alloc_sem is taken in shared mode and released
1246+ * on I/O completion (which may happen asynchronously after returning to
1247+ * the caller).
1248+ *
1249+ * - if the flags value does NOT contain DIO_LOCKING we don't use any
1250+ * internal locking but rather rely on the filesystem to synchronize
1251+ * direct I/O reads/writes versus each other and truncate.
1252+ * For reads and writes both i_mutex and i_alloc_sem are not held on
1253+ * entry and are never taken.
1254+ */
1255+ssize_t
1256+__blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
1257+ struct block_device *bdev, const struct iovec *iov, loff_t offset,
1258+ unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
1259+ dio_submit_t submit_io, int flags)
1260+{
1261+ ssize_t retval;
1262+
1263+ retval = __blockdev_direct_IO_newtrunc(rw, iocb, inode, bdev, iov,
1264+ offset, nr_segs, get_block, end_io, submit_io, flags);
12501265 /*
12511266 * In case of error extending write may have instantiated a few
12521267 * blocks outside i_size. Trim these off again for DIO_LOCKING.
1268+ * NOTE: DIO_NO_LOCK/DIO_OWN_LOCK callers have to handle this in
1269+ * their own manner. This is a further example of where the old
1270+ * truncate sequence is inadequate.
12531271 *
12541272 * NOTE: filesystems with their own locking have to handle this
12551273 * on their own.
@@ -1257,12 +1275,13 @@ __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, · 1 unmodified line
12571275 if (flags & DIO_LOCKING) {
12581276 if (unlikely((rw & WRITE) && retval < 0)) {
12591277 loff_t isize = i_size_read(inode);
1278+ loff_t end = offset + iov_length(iov, nr_segs);
1279+
12601280 if (end > isize)
12611281 vmtruncate(inode, isize);
12621282 }
12631283 }
12641284
1265−out:
12661285 return retval;
12671286 }
12681287 EXPORT_SYMBOL(__blockdev_direct_IO);
fs/libfs.c+76−0
@@ -8,6 +8,7 @@ · 7 unmodified lines
88 #include <linux/slab.h>
99 #include <linux/mount.h>
1010 #include <linux/vfs.h>
11+#include <linux/quotaops.h>
1112 #include <linux/mutex.h>
1213 #include <linux/exportfs.h>
1314 #include <linux/writeback.h>
@@ -325,6 +326,81 @@ int simple_rename(struct inode *old_dir, struct dentry *old_dentry, · 311 unmodified lines
325326 return 0;
326327 }
327328
329+/**
330+ * simple_setsize - handle core mm and vfs requirements for file size change
331+ * @inode: inode
332+ * @newsize: new file size
333+ *
334+ * Returns 0 on success, -error on failure.
335+ *
336+ * simple_setsize must be called with inode_mutex held.
337+ *
338+ * simple_setsize will check that the requested new size is OK (see
339+ * inode_newsize_ok), and then will perform the necessary i_size update
340+ * and pagecache truncation (if necessary). It will be typically be called
341+ * from the filesystem's setattr function when ATTR_SIZE is passed in.
342+ *
343+ * The inode itself must have correct permissions and attributes to allow
344+ * i_size to be changed, this function then just checks that the new size
345+ * requested is valid.
346+ *
347+ * In the case of simple in-memory filesystems with inodes stored solely
348+ * in the inode cache, and file data in the pagecache, nothing more needs
349+ * to be done to satisfy a truncate request. Filesystems with on-disk
350+ * blocks for example will need to free them in the case of truncate, in
351+ * that case it may be easier not to use simple_setsize (but each of its
352+ * components will likely be required at some point to update pagecache
353+ * and inode etc).
354+ */
355+int simple_setsize(struct inode *inode, loff_t newsize)
356+{
357+ loff_t oldsize;
358+ int error;
359+
360+ error = inode_newsize_ok(inode, newsize);
361+ if (error)
362+ return error;
363+
364+ oldsize = inode->i_size;
365+ i_size_write(inode, newsize);
366+ truncate_pagecache(inode, oldsize, newsize);
367+
368+ return error;
369+}
370+EXPORT_SYMBOL(simple_setsize);
371+
372+/**
373+ * simple_setattr - setattr for simple in-memory filesystem
374+ * @dentry: dentry
375+ * @iattr: iattr structure
376+ *
377+ * Returns 0 on success, -error on failure.
378+ *
379+ * simple_setattr implements setattr for an in-memory filesystem which
380+ * does not store its own file data or metadata (eg. uses the page cache
381+ * and inode cache as its data store).
382+ */
383+int simple_setattr(struct dentry *dentry, struct iattr *iattr)
384+{
385+ struct inode *inode = dentry->d_inode;
386+ int error;
387+
388+ error = inode_change_ok(inode, iattr);
389+ if (error)
390+ return error;
391+
392+ if (iattr->ia_valid & ATTR_SIZE) {
393+ error = simple_setsize(inode, iattr->ia_size);
394+ if (error)
395+ return error;
396+ }
397+
398+ generic_setattr(inode, iattr);
399+
400+ return error;
401+}
402+EXPORT_SYMBOL(simple_setattr);
403+
328404 int simple_readpage(struct file *file, struct page *page)
329405 {
330406 clear_highpage(page);
include/linux/buffer_head.h+9−0
@@ -203,6 +203,9 @@ int block_write_full_page_endio(struct page *page, get_block_t *get_block, · 202 unmodified lines
203203 int block_read_full_page(struct page*, get_block_t*);
204204 int block_is_partially_uptodate(struct page *page, read_descriptor_t *desc,
205205 unsigned long from);
206+int block_write_begin_newtrunc(struct file *, struct address_space *,
207+ loff_t, unsigned, unsigned,
208+ struct page **, void **, get_block_t*);
206209 int block_write_begin(struct file *, struct address_space *,
207210 loff_t, unsigned, unsigned,
208211 struct page **, void **, get_block_t*);
@@ -214,6 +217,9 @@ int generic_write_end(struct file *, struct address_space *, · 5 unmodified lines
214217 struct page *, void *);
215218 void page_zero_new_buffers(struct page *page, unsigned from, unsigned to);
216219 int block_prepare_write(struct page*, unsigned, unsigned, get_block_t*);
220+int cont_write_begin_newtrunc(struct file *, struct address_space *, loff_t,
221+ unsigned, unsigned, struct page **, void **,
222+ get_block_t *, loff_t *);
217223 int cont_write_begin(struct file *, struct address_space *, loff_t,
218224 unsigned, unsigned, struct page **, void **,
219225 get_block_t *, loff_t *);
@@ -225,6 +231,9 @@ void block_sync_page(struct page *); · 5 unmodified lines
225231 sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *);
226232 int block_truncate_page(struct address_space *, loff_t, get_block_t *);
227233 int file_fsync(struct file *, int);
234+int nobh_write_begin_newtrunc(struct file *, struct address_space *,
235+ loff_t, unsigned, unsigned,
236+ struct page **, void **, get_block_t*);
228237 int nobh_write_begin(struct file *, struct address_space *,
229238 loff_t, unsigned, unsigned,
230239 struct page **, void **, get_block_t*);
include/linux/fs.h+26−1
@@ -2257,6 +2257,10 @@ typedef void (dio_submit_t)(int rw, struct bio *bio, struct inode *inode, · 2256 unmodified lines
22572257 loff_t file_offset);
22582258 void dio_end_io(struct bio *bio, int error);
22592259
2260+ssize_t __blockdev_direct_IO_newtrunc(int rw, struct kiocb *iocb, struct inode *inode,
2261+ struct block_device *bdev, const struct iovec *iov, loff_t offset,
2262+ unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
2263+ dio_submit_t submit_io, int lock_type);
22602264 ssize_t __blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
22612265 struct block_device *bdev, const struct iovec *iov, loff_t offset,
22622266 unsigned long nr_segs, get_block_t get_block, dio_iodone_t end_io,
@@ -2270,6 +2274,24 @@ enum { · 7 unmodified lines
22702274 DIO_SKIP_HOLES = 0x02,
22712275 };
22722276
2277+static inline ssize_t blockdev_direct_IO_newtrunc(int rw, struct kiocb *iocb,
2278+ struct inode *inode, struct block_device *bdev, const struct iovec *iov,
2279+ loff_t offset, unsigned long nr_segs, get_block_t get_block,
2280+ dio_iodone_t end_io)
2281+{
2282+ return __blockdev_direct_IO_newtrunc(rw, iocb, inode, bdev, iov, offset,
2283+ nr_segs, get_block, end_io, NULL,
2284+ DIO_LOCKING | DIO_SKIP_HOLES);
2285+}
2286+
2287+static inline ssize_t blockdev_direct_IO_no_locking_newtrunc(int rw, struct kiocb *iocb,
2288+ struct inode *inode, struct block_device *bdev, const struct iovec *iov,
2289+ loff_t offset, unsigned long nr_segs, get_block_t get_block,
2290+ dio_iodone_t end_io)
2291+{
2292+ return __blockdev_direct_IO_newtrunc(rw, iocb, inode, bdev, iov, offset,
2293+ nr_segs, get_block, end_io, NULL, 0);
2294+}
22732295 static inline ssize_t blockdev_direct_IO(int rw, struct kiocb *iocb,
22742296 struct inode *inode, struct block_device *bdev, const struct iovec *iov,
22752297 loff_t offset, unsigned long nr_segs, get_block_t get_block,
@@ -2342,12 +2364,14 @@ extern int dcache_dir_open(struct inode *, struct file *); · 66 unmodified lines
23422364 extern int dcache_dir_close(struct inode *, struct file *);
23432365 extern loff_t dcache_dir_lseek(struct file *, loff_t, int);
23442366 extern int dcache_readdir(struct file *, void *, filldir_t);
2367+extern int simple_setattr(struct dentry *, struct iattr *);
23452368 extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *);
23462369 extern int simple_statfs(struct dentry *, struct kstatfs *);
23472370 extern int simple_link(struct dentry *, struct inode *, struct dentry *);
23482371 extern int simple_unlink(struct inode *, struct dentry *);
23492372 extern int simple_rmdir(struct inode *, struct dentry *);
23502373 extern int simple_rename(struct inode *, struct dentry *, struct inode *, struct dentry *);
2374+extern int simple_setsize(struct inode *, loff_t);
23512375 extern int noop_fsync(struct file *, int);
23522376 extern int simple_empty(struct dentry *);
23532377 extern int simple_readpage(struct file *file, struct page *page);
@@ -2384,7 +2408,8 @@ extern int buffer_migrate_page(struct address_space *, · 30 unmodified lines
23842408
23852409 extern int inode_change_ok(const struct inode *, struct iattr *);
23862410 extern int inode_newsize_ok(const struct inode *, loff_t offset);
2387−extern int __must_check inode_setattr(struct inode *, struct iattr *);
2411+extern int __must_check inode_setattr(struct inode *, const struct iattr *);
2412+extern void generic_setattr(struct inode *inode, const struct iattr *attr);
23882413
23892414 extern void file_update_time(struct file *file);
23902415
mm/truncate.c+5−5
@@ -548,18 +548,18 @@ EXPORT_SYMBOL(truncate_pagecache); · 547 unmodified lines
548548 * NOTE! We have to be ready to update the memory sharing
549549 * between the file and the memory map for a potential last
550550 * incomplete page. Ugly, but necessary.
551+ *
552+ * This function is deprecated and simple_setsize or truncate_pagecache
553+ * should be used instead.
551554 */
552555 int vmtruncate(struct inode *inode, loff_t offset)
553556 {
554− loff_t oldsize;
555557 int error;
556558
557− error = inode_newsize_ok(inode, offset);
559+ error = simple_setsize(inode, offset);
558560 if (error)
559561 return error;
560− oldsize = inode->i_size;
561− i_size_write(inode, offset);
562− truncate_pagecache(inode, oldsize, offset);
562+
563563 if (inode->i_op->truncate)
564564 inode->i_op->truncate(inode);
565565

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t