diff options
Diffstat (limited to 'fs/buffer.c')
-rw-r--r-- | fs/buffer.c | 57 |
1 files changed, 18 insertions, 39 deletions
diff --git a/fs/buffer.c b/fs/buffer.c index 0befa724ab98..13e5938a64f6 100644 --- a/fs/buffer.c +++ b/fs/buffer.c | |||
@@ -331,7 +331,7 @@ int file_fsync(struct file *filp, struct dentry *dentry, int datasync) | |||
331 | return ret; | 331 | return ret; |
332 | } | 332 | } |
333 | 333 | ||
334 | asmlinkage long sys_fsync(unsigned int fd) | 334 | static long do_fsync(unsigned int fd, int datasync) |
335 | { | 335 | { |
336 | struct file * file; | 336 | struct file * file; |
337 | struct address_space *mapping; | 337 | struct address_space *mapping; |
@@ -342,14 +342,14 @@ asmlinkage long sys_fsync(unsigned int fd) | |||
342 | if (!file) | 342 | if (!file) |
343 | goto out; | 343 | goto out; |
344 | 344 | ||
345 | mapping = file->f_mapping; | ||
346 | |||
347 | ret = -EINVAL; | 345 | ret = -EINVAL; |
348 | if (!file->f_op || !file->f_op->fsync) { | 346 | if (!file->f_op || !file->f_op->fsync) { |
349 | /* Why? We can still call filemap_fdatawrite */ | 347 | /* Why? We can still call filemap_fdatawrite */ |
350 | goto out_putf; | 348 | goto out_putf; |
351 | } | 349 | } |
352 | 350 | ||
351 | mapping = file->f_mapping; | ||
352 | |||
353 | current->flags |= PF_SYNCWRITE; | 353 | current->flags |= PF_SYNCWRITE; |
354 | ret = filemap_fdatawrite(mapping); | 354 | ret = filemap_fdatawrite(mapping); |
355 | 355 | ||
@@ -358,7 +358,7 @@ asmlinkage long sys_fsync(unsigned int fd) | |||
358 | * which could cause livelocks in fsync_buffers_list | 358 | * which could cause livelocks in fsync_buffers_list |
359 | */ | 359 | */ |
360 | down(&mapping->host->i_sem); | 360 | down(&mapping->host->i_sem); |
361 | err = file->f_op->fsync(file, file->f_dentry, 0); | 361 | err = file->f_op->fsync(file, file->f_dentry, datasync); |
362 | if (!ret) | 362 | if (!ret) |
363 | ret = err; | 363 | ret = err; |
364 | up(&mapping->host->i_sem); | 364 | up(&mapping->host->i_sem); |
@@ -373,39 +373,14 @@ out: | |||
373 | return ret; | 373 | return ret; |
374 | } | 374 | } |
375 | 375 | ||
376 | asmlinkage long sys_fdatasync(unsigned int fd) | 376 | asmlinkage long sys_fsync(unsigned int fd) |
377 | { | 377 | { |
378 | struct file * file; | 378 | return do_fsync(fd, 0); |
379 | struct address_space *mapping; | 379 | } |
380 | int ret, err; | ||
381 | |||
382 | ret = -EBADF; | ||
383 | file = fget(fd); | ||
384 | if (!file) | ||
385 | goto out; | ||
386 | |||
387 | ret = -EINVAL; | ||
388 | if (!file->f_op || !file->f_op->fsync) | ||
389 | goto out_putf; | ||
390 | |||
391 | mapping = file->f_mapping; | ||
392 | |||
393 | current->flags |= PF_SYNCWRITE; | ||
394 | ret = filemap_fdatawrite(mapping); | ||
395 | down(&mapping->host->i_sem); | ||
396 | err = file->f_op->fsync(file, file->f_dentry, 1); | ||
397 | if (!ret) | ||
398 | ret = err; | ||
399 | up(&mapping->host->i_sem); | ||
400 | err = filemap_fdatawait(mapping); | ||
401 | if (!ret) | ||
402 | ret = err; | ||
403 | current->flags &= ~PF_SYNCWRITE; | ||
404 | 380 | ||
405 | out_putf: | 381 | asmlinkage long sys_fdatasync(unsigned int fd) |
406 | fput(file); | 382 | { |
407 | out: | 383 | return do_fsync(fd, 1); |
408 | return ret; | ||
409 | } | 384 | } |
410 | 385 | ||
411 | /* | 386 | /* |
@@ -1951,7 +1926,6 @@ static int __block_prepare_write(struct inode *inode, struct page *page, | |||
1951 | if (err) | 1926 | if (err) |
1952 | break; | 1927 | break; |
1953 | if (buffer_new(bh)) { | 1928 | if (buffer_new(bh)) { |
1954 | clear_buffer_new(bh); | ||
1955 | unmap_underlying_metadata(bh->b_bdev, | 1929 | unmap_underlying_metadata(bh->b_bdev, |
1956 | bh->b_blocknr); | 1930 | bh->b_blocknr); |
1957 | if (PageUptodate(page)) { | 1931 | if (PageUptodate(page)) { |
@@ -1993,9 +1967,14 @@ static int __block_prepare_write(struct inode *inode, struct page *page, | |||
1993 | if (!buffer_uptodate(*wait_bh)) | 1967 | if (!buffer_uptodate(*wait_bh)) |
1994 | err = -EIO; | 1968 | err = -EIO; |
1995 | } | 1969 | } |
1996 | if (!err) | 1970 | if (!err) { |
1997 | return err; | 1971 | bh = head; |
1998 | 1972 | do { | |
1973 | if (buffer_new(bh)) | ||
1974 | clear_buffer_new(bh); | ||
1975 | } while ((bh = bh->b_this_page) != head); | ||
1976 | return 0; | ||
1977 | } | ||
1999 | /* Error case: */ | 1978 | /* Error case: */ |
2000 | /* | 1979 | /* |
2001 | * Zero out any newly allocated blocks to avoid exposing stale | 1980 | * Zero out any newly allocated blocks to avoid exposing stale |