Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
07931b7b
Commit
07931b7b
authored
Jun 21, 2016
by
Dave Chinner
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'fs-4.8-iomap-infrastructure' into for-next
parents
26f1fe85
8be9f564
Changes
10
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
649 additions
and
20 deletions
+649
-20
fs/Kconfig
fs/Kconfig
+3
-0
fs/Makefile
fs/Makefile
+1
-0
fs/buffer.c
fs/buffer.c
+71
-5
fs/internal.h
fs/internal.h
+3
-0
fs/iomap.c
fs/iomap.c
+497
-0
fs/nfsd/blocklayout.c
fs/nfsd/blocklayout.c
+1
-0
fs/nfsd/blocklayoutxdr.c
fs/nfsd/blocklayoutxdr.c
+1
-0
fs/xfs/xfs_pnfs.c
fs/xfs/xfs_pnfs.c
+1
-0
include/linux/exportfs.h
include/linux/exportfs.h
+1
-15
include/linux/iomap.h
include/linux/iomap.h
+70
-0
No files found.
fs/Kconfig
View file @
07931b7b
...
...
@@ -10,6 +10,9 @@ config DCACHE_WORD_ACCESS
if BLOCK
config FS_IOMAP
bool
source "fs/ext2/Kconfig"
source "fs/ext4/Kconfig"
source "fs/jbd2/Kconfig"
...
...
fs/Makefile
View file @
07931b7b
...
...
@@ -49,6 +49,7 @@ obj-$(CONFIG_COREDUMP) += coredump.o
obj-$(CONFIG_SYSCTL)
+=
drop_caches.o
obj-$(CONFIG_FHANDLE)
+=
fhandle.o
obj-$(CONFIG_FS_IOMAP)
+=
iomap.o
obj-y
+=
quota/
...
...
fs/buffer.c
View file @
07931b7b
...
...
@@ -21,6 +21,7 @@
#include <linux/kernel.h>
#include <linux/syscalls.h>
#include <linux/fs.h>
#include <linux/iomap.h>
#include <linux/mm.h>
#include <linux/percpu.h>
#include <linux/slab.h>
...
...
@@ -1891,8 +1892,62 @@ void page_zero_new_buffers(struct page *page, unsigned from, unsigned to)
}
EXPORT_SYMBOL
(
page_zero_new_buffers
);
int
__block_write_begin
(
struct
page
*
page
,
loff_t
pos
,
unsigned
len
,
get_block_t
*
get_block
)
static
void
iomap_to_bh
(
struct
inode
*
inode
,
sector_t
block
,
struct
buffer_head
*
bh
,
struct
iomap
*
iomap
)
{
loff_t
offset
=
block
<<
inode
->
i_blkbits
;
bh
->
b_bdev
=
iomap
->
bdev
;
/*
* Block points to offset in file we need to map, iomap contains
* the offset at which the map starts. If the map ends before the
* current block, then do not map the buffer and let the caller
* handle it.
*/
BUG_ON
(
offset
>=
iomap
->
offset
+
iomap
->
length
);
switch
(
iomap
->
type
)
{
case
IOMAP_HOLE
:
/*
* If the buffer is not up to date or beyond the current EOF,
* we need to mark it as new to ensure sub-block zeroing is
* executed if necessary.
*/
if
(
!
buffer_uptodate
(
bh
)
||
(
offset
>=
i_size_read
(
inode
)))
set_buffer_new
(
bh
);
break
;
case
IOMAP_DELALLOC
:
if
(
!
buffer_uptodate
(
bh
)
||
(
offset
>=
i_size_read
(
inode
)))
set_buffer_new
(
bh
);
set_buffer_uptodate
(
bh
);
set_buffer_mapped
(
bh
);
set_buffer_delay
(
bh
);
break
;
case
IOMAP_UNWRITTEN
:
/*
* For unwritten regions, we always need to ensure that
* sub-block writes cause the regions in the block we are not
* writing to are zeroed. Set the buffer as new to ensure this.
*/
set_buffer_new
(
bh
);
set_buffer_unwritten
(
bh
);
/* FALLTHRU */
case
IOMAP_MAPPED
:
if
(
offset
>=
i_size_read
(
inode
))
set_buffer_new
(
bh
);
bh
->
b_blocknr
=
(
iomap
->
blkno
>>
(
inode
->
i_blkbits
-
9
))
+
((
offset
-
iomap
->
offset
)
>>
inode
->
i_blkbits
);
set_buffer_mapped
(
bh
);
break
;
}
}
int
__block_write_begin_int
(
struct
page
*
page
,
loff_t
pos
,
unsigned
len
,
get_block_t
*
get_block
,
struct
iomap
*
iomap
)
{
unsigned
from
=
pos
&
(
PAGE_SIZE
-
1
);
unsigned
to
=
from
+
len
;
...
...
@@ -1928,9 +1983,14 @@ int __block_write_begin(struct page *page, loff_t pos, unsigned len,
clear_buffer_new
(
bh
);
if
(
!
buffer_mapped
(
bh
))
{
WARN_ON
(
bh
->
b_size
!=
blocksize
);
err
=
get_block
(
inode
,
block
,
bh
,
1
);
if
(
err
)
break
;
if
(
get_block
)
{
err
=
get_block
(
inode
,
block
,
bh
,
1
);
if
(
err
)
break
;
}
else
{
iomap_to_bh
(
inode
,
block
,
bh
,
iomap
);
}
if
(
buffer_new
(
bh
))
{
unmap_underlying_metadata
(
bh
->
b_bdev
,
bh
->
b_blocknr
);
...
...
@@ -1971,6 +2031,12 @@ int __block_write_begin(struct page *page, loff_t pos, unsigned len,
page_zero_new_buffers
(
page
,
from
,
to
);
return
err
;
}
int
__block_write_begin
(
struct
page
*
page
,
loff_t
pos
,
unsigned
len
,
get_block_t
*
get_block
)
{
return
__block_write_begin_int
(
page
,
pos
,
len
,
get_block
,
NULL
);
}
EXPORT_SYMBOL
(
__block_write_begin
);
static
int
__block_commit_write
(
struct
inode
*
inode
,
struct
page
*
page
,
...
...
fs/internal.h
View file @
07931b7b
...
...
@@ -11,6 +11,7 @@
struct
super_block
;
struct
file_system_type
;
struct
iomap
;
struct
linux_binprm
;
struct
path
;
struct
mount
;
...
...
@@ -39,6 +40,8 @@ static inline int __sync_blockdev(struct block_device *bdev, int wait)
* buffer.c
*/
extern
void
guard_bio_eod
(
int
rw
,
struct
bio
*
bio
);
extern
int
__block_write_begin_int
(
struct
page
*
page
,
loff_t
pos
,
unsigned
len
,
get_block_t
*
get_block
,
struct
iomap
*
iomap
);
/*
* char_dev.c
...
...
fs/iomap.c
0 → 100644
View file @
07931b7b
This diff is collapsed.
Click to expand it.
fs/nfsd/blocklayout.c
View file @
07931b7b
...
...
@@ -2,6 +2,7 @@
* Copyright (c) 2014-2016 Christoph Hellwig.
*/
#include <linux/exportfs.h>
#include <linux/iomap.h>
#include <linux/genhd.h>
#include <linux/slab.h>
#include <linux/pr.h>
...
...
fs/nfsd/blocklayoutxdr.c
View file @
07931b7b
...
...
@@ -3,6 +3,7 @@
*/
#include <linux/sunrpc/svc.h>
#include <linux/exportfs.h>
#include <linux/iomap.h>
#include <linux/nfs4.h>
#include "nfsd.h"
...
...
fs/xfs/xfs_pnfs.c
View file @
07931b7b
/*
* Copyright (c) 2014 Christoph Hellwig.
*/
#include <linux/iomap.h>
#include "xfs.h"
#include "xfs_format.h"
#include "xfs_log_format.h"
...
...
include/linux/exportfs.h
View file @
07931b7b
...
...
@@ -6,6 +6,7 @@
struct
dentry
;
struct
iattr
;
struct
inode
;
struct
iomap
;
struct
super_block
;
struct
vfsmount
;
...
...
@@ -187,21 +188,6 @@ struct fid {
* get_name is not (which is possibly inconsistent)
*/
/* types of block ranges for multipage write mappings. */
#define IOMAP_HOLE 0x01
/* no blocks allocated, need allocation */
#define IOMAP_DELALLOC 0x02
/* delayed allocation blocks */
#define IOMAP_MAPPED 0x03
/* blocks allocated @blkno */
#define IOMAP_UNWRITTEN 0x04
/* blocks allocated @blkno in unwritten state */
#define IOMAP_NULL_BLOCK -1LL
/* blkno is not valid */
struct
iomap
{
sector_t
blkno
;
/* first sector of mapping */
loff_t
offset
;
/* file offset of mapping, bytes */
u64
length
;
/* length of mapping, bytes */
int
type
;
/* type of mapping */
};
struct
export_operations
{
int
(
*
encode_fh
)(
struct
inode
*
inode
,
__u32
*
fh
,
int
*
max_len
,
struct
inode
*
parent
);
...
...
include/linux/iomap.h
0 → 100644
View file @
07931b7b
#ifndef LINUX_IOMAP_H
#define LINUX_IOMAP_H 1
#include <linux/types.h>
struct
fiemap_extent_info
;
struct
inode
;
struct
iov_iter
;
struct
kiocb
;
struct
vm_area_struct
;
struct
vm_fault
;
/*
* Types of block ranges for iomap mappings:
*/
#define IOMAP_HOLE 0x01
/* no blocks allocated, need allocation */
#define IOMAP_DELALLOC 0x02
/* delayed allocation blocks */
#define IOMAP_MAPPED 0x03
/* blocks allocated @blkno */
#define IOMAP_UNWRITTEN 0x04
/* blocks allocated @blkno in unwritten state */
/*
* Magic value for blkno:
*/
#define IOMAP_NULL_BLOCK -1LL
/* blkno is not valid */
struct
iomap
{
sector_t
blkno
;
/* 1st sector of mapping, 512b units */
loff_t
offset
;
/* file offset of mapping, bytes */
u64
length
;
/* length of mapping, bytes */
int
type
;
/* type of mapping */
struct
block_device
*
bdev
;
/* block device for I/O */
};
/*
* Flags for iomap_begin / iomap_end. No flag implies a read.
*/
#define IOMAP_WRITE (1 << 0)
#define IOMAP_ZERO (1 << 1)
struct
iomap_ops
{
/*
* Return the existing mapping at pos, or reserve space starting at
* pos for up to length, as long as we can do it as a single mapping.
* The actual length is returned in iomap->length.
*/
int
(
*
iomap_begin
)(
struct
inode
*
inode
,
loff_t
pos
,
loff_t
length
,
unsigned
flags
,
struct
iomap
*
iomap
);
/*
* Commit and/or unreserve space previous allocated using iomap_begin.
* Written indicates the length of the successful write operation which
* needs to be commited, while the rest needs to be unreserved.
* Written might be zero if no data was written.
*/
int
(
*
iomap_end
)(
struct
inode
*
inode
,
loff_t
pos
,
loff_t
length
,
ssize_t
written
,
unsigned
flags
,
struct
iomap
*
iomap
);
};
ssize_t
iomap_file_buffered_write
(
struct
kiocb
*
iocb
,
struct
iov_iter
*
from
,
struct
iomap_ops
*
ops
);
int
iomap_zero_range
(
struct
inode
*
inode
,
loff_t
pos
,
loff_t
len
,
bool
*
did_zero
,
struct
iomap_ops
*
ops
);
int
iomap_truncate_page
(
struct
inode
*
inode
,
loff_t
pos
,
bool
*
did_zero
,
struct
iomap_ops
*
ops
);
int
iomap_page_mkwrite
(
struct
vm_area_struct
*
vma
,
struct
vm_fault
*
vmf
,
struct
iomap_ops
*
ops
);
int
iomap_fiemap
(
struct
inode
*
inode
,
struct
fiemap_extent_info
*
fieinfo
,
loff_t
start
,
loff_t
len
,
struct
iomap_ops
*
ops
);
#endif
/* LINUX_IOMAP_H */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment