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
Kirill Smelkov
linux
Commits
57f80c0e
Commit
57f80c0e
authored
Jul 17, 2020
by
Trond Myklebust
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'xattr-devel'
parents
18eb87f4
95ad37f9
Changes
20
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
2269 additions
and
42 deletions
+2269
-42
fs/nfs/Makefile
fs/nfs/Makefile
+1
-1
fs/nfs/client.c
fs/nfs/client.c
+20
-2
fs/nfs/dir.c
fs/nfs/dir.c
+20
-4
fs/nfs/inode.c
fs/nfs/inode.c
+14
-2
fs/nfs/nfs42.h
fs/nfs/nfs42.h
+24
-0
fs/nfs/nfs42proc.c
fs/nfs/nfs42proc.c
+248
-0
fs/nfs/nfs42xattr.c
fs/nfs/nfs42xattr.c
+1083
-0
fs/nfs/nfs42xdr.c
fs/nfs/nfs42xdr.c
+438
-0
fs/nfs/nfs4_fs.h
fs/nfs/nfs4_fs.h
+35
-0
fs/nfs/nfs4client.c
fs/nfs/nfs4client.c
+31
-0
fs/nfs/nfs4proc.c
fs/nfs/nfs4proc.c
+206
-31
fs/nfs/nfs4super.c
fs/nfs/nfs4super.c
+10
-0
fs/nfs/nfs4xdr.c
fs/nfs/nfs4xdr.c
+31
-0
fs/nfs/nfstrace.h
fs/nfs/nfstrace.h
+2
-1
include/linux/nfs4.h
include/linux/nfs4.h
+25
-0
include/linux/nfs_fs.h
include/linux/nfs_fs.h
+12
-0
include/linux/nfs_fs_sb.h
include/linux/nfs_fs_sb.h
+6
-0
include/linux/nfs_xdr.h
include/linux/nfs_xdr.h
+59
-1
include/uapi/linux/nfs4.h
include/uapi/linux/nfs4.h
+3
-0
include/uapi/linux/nfs_fs.h
include/uapi/linux/nfs_fs.h
+1
-0
No files found.
fs/nfs/Makefile
View file @
57f80c0e
...
...
@@ -30,7 +30,7 @@ nfsv4-y := nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o nfs4super.o nfs4file.o
nfsv4-$(CONFIG_NFS_USE_LEGACY_DNS)
+=
cache_lib.o
nfsv4-$(CONFIG_SYSCTL)
+=
nfs4sysctl.o
nfsv4-$(CONFIG_NFS_V4_1)
+=
pnfs.o pnfs_dev.o pnfs_nfs.o
nfsv4-$(CONFIG_NFS_V4_2)
+=
nfs42proc.o
nfsv4-$(CONFIG_NFS_V4_2)
+=
nfs42proc.o
nfs42xattr.o
obj-$(CONFIG_PNFS_FILE_LAYOUT)
+=
filelayout/
obj-$(CONFIG_PNFS_BLOCK)
+=
blocklayout/
...
...
fs/nfs/client.c
View file @
57f80c0e
...
...
@@ -50,6 +50,7 @@
#include "nfs.h"
#include "netns.h"
#include "sysfs.h"
#include "nfs42.h"
#define NFSDBG_FACILITY NFSDBG_CLIENT
...
...
@@ -749,7 +750,7 @@ static int nfs_init_server(struct nfs_server *server,
static
void
nfs_server_set_fsinfo
(
struct
nfs_server
*
server
,
struct
nfs_fsinfo
*
fsinfo
)
{
unsigned
long
max_rpc_payload
;
unsigned
long
max_rpc_payload
,
raw_max_rpc_payload
;
/* Work out a lot of parameters */
if
(
server
->
rsize
==
0
)
...
...
@@ -762,7 +763,9 @@ static void nfs_server_set_fsinfo(struct nfs_server *server,
if
(
fsinfo
->
wtmax
>=
512
&&
server
->
wsize
>
fsinfo
->
wtmax
)
server
->
wsize
=
nfs_block_size
(
fsinfo
->
wtmax
,
NULL
);
max_rpc_payload
=
nfs_block_size
(
rpc_max_payload
(
server
->
client
),
NULL
);
raw_max_rpc_payload
=
rpc_max_payload
(
server
->
client
);
max_rpc_payload
=
nfs_block_size
(
raw_max_rpc_payload
,
NULL
);
if
(
server
->
rsize
>
max_rpc_payload
)
server
->
rsize
=
max_rpc_payload
;
if
(
server
->
rsize
>
NFS_MAX_FILE_IO_SIZE
)
...
...
@@ -795,6 +798,21 @@ static void nfs_server_set_fsinfo(struct nfs_server *server,
server
->
clone_blksize
=
fsinfo
->
clone_blksize
;
/* We're airborne Set socket buffersize */
rpc_setbufsize
(
server
->
client
,
server
->
wsize
+
100
,
server
->
rsize
+
100
);
#ifdef CONFIG_NFS_V4_2
/*
* Defaults until limited by the session parameters.
*/
server
->
gxasize
=
min_t
(
unsigned
int
,
raw_max_rpc_payload
,
XATTR_SIZE_MAX
);
server
->
sxasize
=
min_t
(
unsigned
int
,
raw_max_rpc_payload
,
XATTR_SIZE_MAX
);
server
->
lxasize
=
min_t
(
unsigned
int
,
raw_max_rpc_payload
,
nfs42_listxattr_xdrsize
(
XATTR_LIST_MAX
));
if
(
fsinfo
->
xattr_support
)
server
->
caps
|=
NFS_CAP_XATTR
;
#endif
}
/*
...
...
fs/nfs/dir.c
View file @
57f80c0e
...
...
@@ -2460,7 +2460,7 @@ static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, co
return
NULL
;
}
static
int
nfs_access_get_cached
(
struct
inode
*
inode
,
const
struct
cred
*
cred
,
struct
nfs_access_entry
*
res
,
bool
may_block
)
static
int
nfs_access_get_cached
_locked
(
struct
inode
*
inode
,
const
struct
cred
*
cred
,
struct
nfs_access_entry
*
res
,
bool
may_block
)
{
struct
nfs_inode
*
nfsi
=
NFS_I
(
inode
);
struct
nfs_access_entry
*
cache
;
...
...
@@ -2533,6 +2533,20 @@ static int nfs_access_get_cached_rcu(struct inode *inode, const struct cred *cre
return
err
;
}
int
nfs_access_get_cached
(
struct
inode
*
inode
,
const
struct
cred
*
cred
,
struct
nfs_access_entry
*
res
,
bool
may_block
)
{
int
status
;
status
=
nfs_access_get_cached_rcu
(
inode
,
cred
,
res
);
if
(
status
!=
0
)
status
=
nfs_access_get_cached_locked
(
inode
,
cred
,
res
,
may_block
);
return
status
;
}
EXPORT_SYMBOL_GPL
(
nfs_access_get_cached
);
static
void
nfs_access_add_rbtree
(
struct
inode
*
inode
,
struct
nfs_access_entry
*
set
)
{
struct
nfs_inode
*
nfsi
=
NFS_I
(
inode
);
...
...
@@ -2647,9 +2661,7 @@ static int nfs_do_access(struct inode *inode, const struct cred *cred, int mask)
trace_nfs_access_enter
(
inode
);
status
=
nfs_access_get_cached_rcu
(
inode
,
cred
,
&
cache
);
if
(
status
!=
0
)
status
=
nfs_access_get_cached
(
inode
,
cred
,
&
cache
,
may_block
);
status
=
nfs_access_get_cached
(
inode
,
cred
,
&
cache
,
may_block
);
if
(
status
==
0
)
goto
out_cached
;
...
...
@@ -2661,6 +2673,10 @@ static int nfs_do_access(struct inode *inode, const struct cred *cred, int mask)
* Determine which access bits we want to ask for...
*/
cache
.
mask
=
NFS_ACCESS_READ
|
NFS_ACCESS_MODIFY
|
NFS_ACCESS_EXTEND
;
if
(
nfs_server_capable
(
inode
,
NFS_CAP_XATTR
))
{
cache
.
mask
|=
NFS_ACCESS_XAREAD
|
NFS_ACCESS_XAWRITE
|
NFS_ACCESS_XALIST
;
}
if
(
S_ISDIR
(
inode
->
i_mode
))
cache
.
mask
|=
NFS_ACCESS_DELETE
|
NFS_ACCESS_LOOKUP
;
else
...
...
fs/nfs/inode.c
View file @
57f80c0e
...
...
@@ -193,6 +193,7 @@ bool nfs_check_cache_invalid(struct inode *inode, unsigned long flags)
return
nfs_check_cache_invalid_not_delegated
(
inode
,
flags
);
}
EXPORT_SYMBOL_GPL
(
nfs_check_cache_invalid
);
static
void
nfs_set_cache_invalid
(
struct
inode
*
inode
,
unsigned
long
flags
)
{
...
...
@@ -204,7 +205,8 @@ static void nfs_set_cache_invalid(struct inode *inode, unsigned long flags)
flags
&=
~
NFS_INO_INVALID_OTHER
;
flags
&=
~
(
NFS_INO_INVALID_CHANGE
|
NFS_INO_INVALID_SIZE
|
NFS_INO_REVAL_PAGECACHE
);
|
NFS_INO_REVAL_PAGECACHE
|
NFS_INO_INVALID_XATTR
);
}
if
(
inode
->
i_mapping
->
nrpages
==
0
)
...
...
@@ -233,11 +235,13 @@ static void nfs_zap_caches_locked(struct inode *inode)
|
NFS_INO_INVALID_DATA
|
NFS_INO_INVALID_ACCESS
|
NFS_INO_INVALID_ACL
|
NFS_INO_INVALID_XATTR
|
NFS_INO_REVAL_PAGECACHE
);
}
else
nfs_set_cache_invalid
(
inode
,
NFS_INO_INVALID_ATTR
|
NFS_INO_INVALID_ACCESS
|
NFS_INO_INVALID_ACL
|
NFS_INO_INVALID_XATTR
|
NFS_INO_REVAL_PAGECACHE
);
nfs_zap_label_cache_locked
(
nfsi
);
}
...
...
@@ -542,6 +546,8 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
inode
->
i_gid
=
fattr
->
gid
;
else
if
(
nfs_server_capable
(
inode
,
NFS_CAP_OWNER_GROUP
))
nfs_set_cache_invalid
(
inode
,
NFS_INO_INVALID_OTHER
);
if
(
nfs_server_capable
(
inode
,
NFS_CAP_XATTR
))
nfs_set_cache_invalid
(
inode
,
NFS_INO_INVALID_XATTR
);
if
(
fattr
->
valid
&
NFS_ATTR_FATTR_BLOCKS_USED
)
inode
->
i_blocks
=
fattr
->
du
.
nfs2
.
blocks
;
if
(
fattr
->
valid
&
NFS_ATTR_FATTR_SPACE_USED
)
{
...
...
@@ -1377,6 +1383,8 @@ static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr)
inode_set_iversion_raw
(
inode
,
fattr
->
change_attr
);
if
(
S_ISDIR
(
inode
->
i_mode
))
nfs_set_cache_invalid
(
inode
,
NFS_INO_INVALID_DATA
);
else
if
(
nfs_server_capable
(
inode
,
NFS_CAP_XATTR
))
nfs_set_cache_invalid
(
inode
,
NFS_INO_INVALID_XATTR
);
}
/* If we have atomic WCC data, we may update some attributes */
ts
=
inode
->
i_ctime
;
...
...
@@ -1894,7 +1902,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
if
(
!
(
have_writers
||
have_delegation
))
{
invalid
|=
NFS_INO_INVALID_DATA
|
NFS_INO_INVALID_ACCESS
|
NFS_INO_INVALID_ACL
;
|
NFS_INO_INVALID_ACL
|
NFS_INO_INVALID_XATTR
;
/* Force revalidate of all attributes */
save_cache_validity
|=
NFS_INO_INVALID_CTIME
|
NFS_INO_INVALID_MTIME
...
...
@@ -2097,6 +2106,9 @@ struct inode *nfs_alloc_inode(struct super_block *sb)
#if IS_ENABLED(CONFIG_NFS_V4)
nfsi
->
nfs4_acl
=
NULL
;
#endif
/* CONFIG_NFS_V4 */
#ifdef CONFIG_NFS_V4_2
nfsi
->
xattr_cache
=
NULL
;
#endif
return
&
nfsi
->
vfs_inode
;
}
EXPORT_SYMBOL_GPL
(
nfs_alloc_inode
);
...
...
fs/nfs/nfs42.h
View file @
57f80c0e
...
...
@@ -6,6 +6,8 @@
#ifndef __LINUX_FS_NFS_NFS4_2_H
#define __LINUX_FS_NFS_NFS4_2_H
#include <linux/xattr.h>
/*
* FIXME: four LAYOUTSTATS calls per compound at most! Do we need to support
* more? Need to consider not to pre-alloc too much for a compound.
...
...
@@ -36,5 +38,27 @@ static inline bool nfs42_files_from_same_server(struct file *in,
return
nfs4_check_serverowner_major_id
(
c_in
->
cl_serverowner
,
c_out
->
cl_serverowner
);
}
ssize_t
nfs42_proc_getxattr
(
struct
inode
*
inode
,
const
char
*
name
,
void
*
buf
,
size_t
buflen
);
int
nfs42_proc_setxattr
(
struct
inode
*
inode
,
const
char
*
name
,
const
void
*
buf
,
size_t
buflen
,
int
flags
);
ssize_t
nfs42_proc_listxattrs
(
struct
inode
*
inode
,
void
*
buf
,
size_t
buflen
,
u64
*
cookiep
,
bool
*
eofp
);
int
nfs42_proc_removexattr
(
struct
inode
*
inode
,
const
char
*
name
);
/*
* Maximum XDR buffer size needed for a listxattr buffer of buflen size.
*
* The upper boundary is a buffer with all 1-byte sized attribute names.
* They would be 7 bytes long in the eventual buffer ("user.x\0"), and
* 8 bytes long XDR-encoded.
*
* Include the trailing eof word as well.
*/
static
inline
u32
nfs42_listxattr_xdrsize
(
u32
buflen
)
{
return
((
buflen
/
(
XATTR_USER_PREFIX_LEN
+
2
))
*
8
)
+
4
;
}
#endif
/* CONFIG_NFS_V4_2 */
#endif
/* __LINUX_FS_NFS_NFS4_2_H */
fs/nfs/nfs42proc.c
View file @
57f80c0e
...
...
@@ -1088,3 +1088,251 @@ int nfs42_proc_clone(struct file *src_f, struct file *dst_f,
nfs_put_lock_context
(
src_lock
);
return
err
;
}
#define NFS4XATTR_MAXPAGES DIV_ROUND_UP(XATTR_SIZE_MAX, PAGE_SIZE)
static
int
_nfs42_proc_removexattr
(
struct
inode
*
inode
,
const
char
*
name
)
{
struct
nfs_server
*
server
=
NFS_SERVER
(
inode
);
struct
nfs42_removexattrargs
args
=
{
.
fh
=
NFS_FH
(
inode
),
.
xattr_name
=
name
,
};
struct
nfs42_removexattrres
res
;
struct
rpc_message
msg
=
{
.
rpc_proc
=
&
nfs4_procedures
[
NFSPROC4_CLNT_REMOVEXATTR
],
.
rpc_argp
=
&
args
,
.
rpc_resp
=
&
res
,
};
int
ret
;
unsigned
long
timestamp
=
jiffies
;
ret
=
nfs4_call_sync
(
server
->
client
,
server
,
&
msg
,
&
args
.
seq_args
,
&
res
.
seq_res
,
1
);
if
(
!
ret
)
nfs4_update_changeattr
(
inode
,
&
res
.
cinfo
,
timestamp
,
0
);
return
ret
;
}
static
int
_nfs42_proc_setxattr
(
struct
inode
*
inode
,
const
char
*
name
,
const
void
*
buf
,
size_t
buflen
,
int
flags
)
{
struct
nfs_server
*
server
=
NFS_SERVER
(
inode
);
struct
page
*
pages
[
NFS4XATTR_MAXPAGES
];
struct
nfs42_setxattrargs
arg
=
{
.
fh
=
NFS_FH
(
inode
),
.
xattr_pages
=
pages
,
.
xattr_len
=
buflen
,
.
xattr_name
=
name
,
.
xattr_flags
=
flags
,
};
struct
nfs42_setxattrres
res
;
struct
rpc_message
msg
=
{
.
rpc_proc
=
&
nfs4_procedures
[
NFSPROC4_CLNT_SETXATTR
],
.
rpc_argp
=
&
arg
,
.
rpc_resp
=
&
res
,
};
int
ret
,
np
;
unsigned
long
timestamp
=
jiffies
;
if
(
buflen
>
server
->
sxasize
)
return
-
ERANGE
;
if
(
buflen
>
0
)
{
np
=
nfs4_buf_to_pages_noslab
(
buf
,
buflen
,
arg
.
xattr_pages
);
if
(
np
<
0
)
return
np
;
}
else
np
=
0
;
ret
=
nfs4_call_sync
(
server
->
client
,
server
,
&
msg
,
&
arg
.
seq_args
,
&
res
.
seq_res
,
1
);
for
(;
np
>
0
;
np
--
)
put_page
(
pages
[
np
-
1
]);
if
(
!
ret
)
nfs4_update_changeattr
(
inode
,
&
res
.
cinfo
,
timestamp
,
0
);
return
ret
;
}
static
ssize_t
_nfs42_proc_getxattr
(
struct
inode
*
inode
,
const
char
*
name
,
void
*
buf
,
size_t
buflen
)
{
struct
nfs_server
*
server
=
NFS_SERVER
(
inode
);
struct
page
*
pages
[
NFS4XATTR_MAXPAGES
]
=
{};
struct
nfs42_getxattrargs
arg
=
{
.
fh
=
NFS_FH
(
inode
),
.
xattr_pages
=
pages
,
.
xattr_len
=
buflen
,
.
xattr_name
=
name
,
};
struct
nfs42_getxattrres
res
;
struct
rpc_message
msg
=
{
.
rpc_proc
=
&
nfs4_procedures
[
NFSPROC4_CLNT_GETXATTR
],
.
rpc_argp
=
&
arg
,
.
rpc_resp
=
&
res
,
};
int
ret
,
np
;
ret
=
nfs4_call_sync
(
server
->
client
,
server
,
&
msg
,
&
arg
.
seq_args
,
&
res
.
seq_res
,
0
);
if
(
ret
<
0
)
return
ret
;
/*
* Normally, the caching is done one layer up, but for successful
* RPCS, always cache the result here, even if the caller was
* just querying the length, or if the reply was too big for
* the caller. This avoids a second RPC in the case of the
* common query-alloc-retrieve cycle for xattrs.
*
* Note that xattr_len is always capped to XATTR_SIZE_MAX.
*/
nfs4_xattr_cache_add
(
inode
,
name
,
NULL
,
pages
,
res
.
xattr_len
);
if
(
buflen
)
{
if
(
res
.
xattr_len
>
buflen
)
return
-
ERANGE
;
_copy_from_pages
(
buf
,
pages
,
0
,
res
.
xattr_len
);
}
np
=
DIV_ROUND_UP
(
res
.
xattr_len
,
PAGE_SIZE
);
while
(
--
np
>=
0
)
__free_page
(
pages
[
np
]);
return
res
.
xattr_len
;
}
static
ssize_t
_nfs42_proc_listxattrs
(
struct
inode
*
inode
,
void
*
buf
,
size_t
buflen
,
u64
*
cookiep
,
bool
*
eofp
)
{
struct
nfs_server
*
server
=
NFS_SERVER
(
inode
);
struct
page
**
pages
;
struct
nfs42_listxattrsargs
arg
=
{
.
fh
=
NFS_FH
(
inode
),
.
cookie
=
*
cookiep
,
};
struct
nfs42_listxattrsres
res
=
{
.
eof
=
false
,
.
xattr_buf
=
buf
,
.
xattr_len
=
buflen
,
};
struct
rpc_message
msg
=
{
.
rpc_proc
=
&
nfs4_procedures
[
NFSPROC4_CLNT_LISTXATTRS
],
.
rpc_argp
=
&
arg
,
.
rpc_resp
=
&
res
,
};
u32
xdrlen
;
int
ret
,
np
;
res
.
scratch
=
alloc_page
(
GFP_KERNEL
);
if
(
!
res
.
scratch
)
return
-
ENOMEM
;
xdrlen
=
nfs42_listxattr_xdrsize
(
buflen
);
if
(
xdrlen
>
server
->
lxasize
)
xdrlen
=
server
->
lxasize
;
np
=
xdrlen
/
PAGE_SIZE
+
1
;
pages
=
kcalloc
(
np
,
sizeof
(
struct
page
*
),
GFP_KERNEL
);
if
(
pages
==
NULL
)
{
__free_page
(
res
.
scratch
);
return
-
ENOMEM
;
}
arg
.
xattr_pages
=
pages
;
arg
.
count
=
xdrlen
;
ret
=
nfs4_call_sync
(
server
->
client
,
server
,
&
msg
,
&
arg
.
seq_args
,
&
res
.
seq_res
,
0
);
if
(
ret
>=
0
)
{
ret
=
res
.
copied
;
*
cookiep
=
res
.
cookie
;
*
eofp
=
res
.
eof
;
}
while
(
--
np
>=
0
)
{
if
(
pages
[
np
])
__free_page
(
pages
[
np
]);
}
__free_page
(
res
.
scratch
);
kfree
(
pages
);
return
ret
;
}
ssize_t
nfs42_proc_getxattr
(
struct
inode
*
inode
,
const
char
*
name
,
void
*
buf
,
size_t
buflen
)
{
struct
nfs4_exception
exception
=
{
};
ssize_t
err
;
do
{
err
=
_nfs42_proc_getxattr
(
inode
,
name
,
buf
,
buflen
);
if
(
err
>=
0
)
break
;
err
=
nfs4_handle_exception
(
NFS_SERVER
(
inode
),
err
,
&
exception
);
}
while
(
exception
.
retry
);
return
err
;
}
int
nfs42_proc_setxattr
(
struct
inode
*
inode
,
const
char
*
name
,
const
void
*
buf
,
size_t
buflen
,
int
flags
)
{
struct
nfs4_exception
exception
=
{
};
int
err
;
do
{
err
=
_nfs42_proc_setxattr
(
inode
,
name
,
buf
,
buflen
,
flags
);
if
(
!
err
)
break
;
err
=
nfs4_handle_exception
(
NFS_SERVER
(
inode
),
err
,
&
exception
);
}
while
(
exception
.
retry
);
return
err
;
}
ssize_t
nfs42_proc_listxattrs
(
struct
inode
*
inode
,
void
*
buf
,
size_t
buflen
,
u64
*
cookiep
,
bool
*
eofp
)
{
struct
nfs4_exception
exception
=
{
};
ssize_t
err
;
do
{
err
=
_nfs42_proc_listxattrs
(
inode
,
buf
,
buflen
,
cookiep
,
eofp
);
if
(
err
>=
0
)
break
;
err
=
nfs4_handle_exception
(
NFS_SERVER
(
inode
),
err
,
&
exception
);
}
while
(
exception
.
retry
);
return
err
;
}
int
nfs42_proc_removexattr
(
struct
inode
*
inode
,
const
char
*
name
)
{
struct
nfs4_exception
exception
=
{
};
int
err
;
do
{
err
=
_nfs42_proc_removexattr
(
inode
,
name
);
if
(
!
err
)
break
;
err
=
nfs4_handle_exception
(
NFS_SERVER
(
inode
),
err
,
&
exception
);
}
while
(
exception
.
retry
);
return
err
;
}
fs/nfs/nfs42xattr.c
0 → 100644
View file @
57f80c0e
This diff is collapsed.
Click to expand it.
fs/nfs/nfs42xdr.c
View file @
57f80c0e
This diff is collapsed.
Click to expand it.
fs/nfs/nfs4_fs.h
View file @
57f80c0e
...
...
@@ -324,6 +324,13 @@ extern int update_open_stateid(struct nfs4_state *state,
extern
int
nfs4_proc_get_lease_time
(
struct
nfs_client
*
clp
,
struct
nfs_fsinfo
*
fsinfo
);
extern
void
nfs4_update_changeattr
(
struct
inode
*
dir
,
struct
nfs4_change_info
*
cinfo
,
unsigned
long
timestamp
,
unsigned
long
cache_validity
);
extern
int
nfs4_buf_to_pages_noslab
(
const
void
*
buf
,
size_t
buflen
,
struct
page
**
pages
);
#if defined(CONFIG_NFS_V4_1)
extern
int
nfs41_sequence_done
(
struct
rpc_task
*
,
struct
nfs4_sequence_res
*
);
extern
int
nfs4_proc_create_session
(
struct
nfs_client
*
,
const
struct
cred
*
);
...
...
@@ -557,6 +564,12 @@ static inline void nfs4_unregister_sysctl(void)
/* nfs4xdr.c */
extern
const
struct
rpc_procinfo
nfs4_procedures
[];
#ifdef CONFIG_NFS_V4_2
extern
const
u32
nfs42_maxsetxattr_overhead
;
extern
const
u32
nfs42_maxgetxattr_overhead
;
extern
const
u32
nfs42_maxlistxattrs_overhead
;
#endif
struct
nfs4_mount_data
;
/* callback_xdr.c */
...
...
@@ -613,12 +626,34 @@ static inline bool nfs4_state_match_open_stateid_other(const struct nfs4_state *
nfs4_stateid_match_other
(
&
state
->
open_stateid
,
stateid
);
}
/* nfs42xattr.c */
#ifdef CONFIG_NFS_V4_2
extern
int
__init
nfs4_xattr_cache_init
(
void
);
extern
void
nfs4_xattr_cache_exit
(
void
);
extern
void
nfs4_xattr_cache_add
(
struct
inode
*
inode
,
const
char
*
name
,
const
char
*
buf
,
struct
page
**
pages
,
ssize_t
buflen
);
extern
void
nfs4_xattr_cache_remove
(
struct
inode
*
inode
,
const
char
*
name
);
extern
ssize_t
nfs4_xattr_cache_get
(
struct
inode
*
inode
,
const
char
*
name
,
char
*
buf
,
ssize_t
buflen
);
extern
void
nfs4_xattr_cache_set_list
(
struct
inode
*
inode
,
const
char
*
buf
,
ssize_t
buflen
);
extern
ssize_t
nfs4_xattr_cache_list
(
struct
inode
*
inode
,
char
*
buf
,
ssize_t
buflen
);
extern
void
nfs4_xattr_cache_zap
(
struct
inode
*
inode
);
#else
static
inline
void
nfs4_xattr_cache_zap
(
struct
inode
*
inode
)
{
}
#endif
/* CONFIG_NFS_V4_2 */
#else
/* CONFIG_NFS_V4 */
#define nfs4_close_state(a, b) do { } while (0)
#define nfs4_close_sync(a, b) do { } while (0)
#define nfs4_state_protect(a, b, c, d) do { } while (0)
#define nfs4_state_protect_write(a, b, c, d) do { } while (0)
#endif
/* CONFIG_NFS_V4 */
#endif
/* __LINUX_FS_NFS_NFS4_FS.H */
fs/nfs/nfs4client.c
View file @
57f80c0e
...
...
@@ -992,6 +992,36 @@ static void nfs4_session_limit_rwsize(struct nfs_server *server)
#endif
/* CONFIG_NFS_V4_1 */
}
/*
* Limit xattr sizes using the channel attributes.
*/
static
void
nfs4_session_limit_xasize
(
struct
nfs_server
*
server
)
{
#ifdef CONFIG_NFS_V4_2
struct
nfs4_session
*
sess
;
u32
server_gxa_sz
;
u32
server_sxa_sz
;
u32
server_lxa_sz
;
if
(
!
nfs4_has_session
(
server
->
nfs_client
))
return
;
sess
=
server
->
nfs_client
->
cl_session
;
server_gxa_sz
=
sess
->
fc_attrs
.
max_resp_sz
-
nfs42_maxgetxattr_overhead
;
server_sxa_sz
=
sess
->
fc_attrs
.
max_rqst_sz
-
nfs42_maxsetxattr_overhead
;
server_lxa_sz
=
sess
->
fc_attrs
.
max_resp_sz
-
nfs42_maxlistxattrs_overhead
;
if
(
server
->
gxasize
>
server_gxa_sz
)
server
->
gxasize
=
server_gxa_sz
;
if
(
server
->
sxasize
>
server_sxa_sz
)
server
->
sxasize
=
server_sxa_sz
;
if
(
server
->
lxasize
>
server_lxa_sz
)
server
->
lxasize
=
server_lxa_sz
;
#endif
}
static
int
nfs4_server_common_setup
(
struct
nfs_server
*
server
,
struct
nfs_fh
*
mntfh
,
bool
auth_probe
)
{
...
...
@@ -1039,6 +1069,7 @@ static int nfs4_server_common_setup(struct nfs_server *server,
goto
out
;
nfs4_session_limit_rwsize
(
server
);
nfs4_session_limit_xasize
(
server
);
if
(
server
->
namelen
==
0
||
server
->
namelen
>
NFS4_MAXNAMLEN
)
server
->
namelen
=
NFS4_MAXNAMLEN
;
...
...
fs/nfs/nfs4proc.c
View file @
57f80c0e
This diff is collapsed.
Click to expand it.
fs/nfs/nfs4super.c
View file @
57f80c0e
...
...
@@ -69,6 +69,7 @@ static void nfs4_evict_inode(struct inode *inode)
pnfs_destroy_layout
(
NFS_I
(
inode
));
/* First call standard NFS clear_inode() code */
nfs_clear_inode
(
inode
);
nfs4_xattr_cache_zap
(
inode
);
}
struct
nfs_referral_count
{
...
...
@@ -268,6 +269,12 @@ static int __init init_nfs_v4(void)
if
(
err
)
goto
out1
;
#ifdef CONFIG_NFS_V4_2
err
=
nfs4_xattr_cache_init
();
if
(
err
)
goto
out2
;
#endif
err
=
nfs4_register_sysctl
();
if
(
err
)
goto
out2
;
...
...
@@ -288,6 +295,9 @@ static void __exit exit_nfs_v4(void)
nfs4_pnfs_v3_ds_connect_unload
();
unregister_nfs_version
(
&
nfs_v4
);
#ifdef CONFIG_NFS_V4_2
nfs4_xattr_cache_exit
();
#endif
nfs4_unregister_sysctl
();
nfs_idmap_quit
();
nfs_dns_resolver_destroy
();
...
...
fs/nfs/nfs4xdr.c
View file @
57f80c0e
...
...
@@ -4201,6 +4201,26 @@ static int decode_attr_time_modify(struct xdr_stream *xdr, uint32_t *bitmap, str
return
status
;
}
static
int
decode_attr_xattrsupport
(
struct
xdr_stream
*
xdr
,
uint32_t
*
bitmap
,
uint32_t
*
res
)
{
__be32
*
p
;
*
res
=
0
;
if
(
unlikely
(
bitmap
[
2
]
&
(
FATTR4_WORD2_XATTR_SUPPORT
-
1U
)))
return
-
EIO
;
if
(
likely
(
bitmap
[
2
]
&
FATTR4_WORD2_XATTR_SUPPORT
))
{
p
=
xdr_inline_decode
(
xdr
,
4
);
if
(
unlikely
(
!
p
))
return
-
EIO
;
*
res
=
be32_to_cpup
(
p
);
bitmap
[
2
]
&=
~
FATTR4_WORD2_XATTR_SUPPORT
;
}
dprintk
(
"%s: XATTR support=%s
\n
"
,
__func__
,
*
res
==
0
?
"false"
:
"true"
);
return
0
;
}
static
int
verify_attr_len
(
struct
xdr_stream
*
xdr
,
unsigned
int
savep
,
uint32_t
attrlen
)
{
unsigned
int
attrwords
=
XDR_QUADLEN
(
attrlen
);
...
...
@@ -4855,6 +4875,11 @@ static int decode_fsinfo(struct xdr_stream *xdr, struct nfs_fsinfo *fsinfo)
if
(
status
)
goto
xdr_error
;
status
=
decode_attr_xattrsupport
(
xdr
,
bitmap
,
&
fsinfo
->
xattr_support
);
if
(
status
)
goto
xdr_error
;
status
=
verify_attr_len
(
xdr
,
savep
,
attrlen
);
xdr_error:
dprintk
(
"%s: xdr returned %d!
\n
"
,
__func__
,
-
status
);
...
...
@@ -7456,6 +7481,8 @@ static struct {
{
NFS4ERR_SYMLINK
,
-
ELOOP
},
{
NFS4ERR_OP_ILLEGAL
,
-
EOPNOTSUPP
},
{
NFS4ERR_DEADLOCK
,
-
EDEADLK
},
{
NFS4ERR_NOXATTR
,
-
ENODATA
},
{
NFS4ERR_XATTR2BIG
,
-
E2BIG
},
{
-
1
,
-
EIO
}
};
...
...
@@ -7584,6 +7611,10 @@ const struct rpc_procinfo nfs4_procedures[] = {
PROC42
(
COPY_NOTIFY
,
enc_copy_notify
,
dec_copy_notify
),
PROC
(
LOOKUPP
,
enc_lookupp
,
dec_lookupp
),
PROC42
(
LAYOUTERROR
,
enc_layouterror
,
dec_layouterror
),
PROC42
(
GETXATTR
,
enc_getxattr
,
dec_getxattr
),
PROC42
(
SETXATTR
,
enc_setxattr
,
dec_setxattr
),
PROC42
(
LISTXATTRS
,
enc_listxattrs
,
dec_listxattrs
),
PROC42
(
REMOVEXATTR
,
enc_removexattr
,
dec_removexattr
),
};
static
unsigned
int
nfs_version4_counts
[
ARRAY_SIZE
(
nfs4_procedures
)];
...
...
fs/nfs/nfstrace.h
View file @
57f80c0e
...
...
@@ -59,7 +59,8 @@ TRACE_DEFINE_ENUM(NFS_INO_INVALID_OTHER);
{ NFS_INO_INVALID_CTIME, "INVALID_CTIME" }, \
{ NFS_INO_INVALID_MTIME, "INVALID_MTIME" }, \
{ NFS_INO_INVALID_SIZE, "INVALID_SIZE" }, \
{ NFS_INO_INVALID_OTHER, "INVALID_OTHER" })
{ NFS_INO_INVALID_OTHER, "INVALID_OTHER" }, \
{ NFS_INO_INVALID_XATTR, "INVALID_XATTR" })
TRACE_DEFINE_ENUM
(
NFS_INO_ADVISE_RDPLUS
);
TRACE_DEFINE_ENUM
(
NFS_INO_STALE
);
...
...
include/linux/nfs4.h
View file @
57f80c0e
...
...
@@ -150,6 +150,12 @@ enum nfs_opnum4 {
OP_WRITE_SAME
=
70
,
OP_CLONE
=
71
,
/* xattr support (RFC8726) */
OP_GETXATTR
=
72
,
OP_SETXATTR
=
73
,
OP_LISTXATTRS
=
74
,
OP_REMOVEXATTR
=
75
,
OP_ILLEGAL
=
10044
,
};
...
...
@@ -280,6 +286,10 @@ enum nfsstat4 {
NFS4ERR_WRONG_LFS
=
10092
,
NFS4ERR_BADLABEL
=
10093
,
NFS4ERR_OFFLOAD_NO_REQS
=
10094
,
/* xattr (RFC8276) */
NFS4ERR_NOXATTR
=
10095
,
NFS4ERR_XATTR2BIG
=
10096
,
};
static
inline
bool
seqid_mutating_err
(
u32
err
)
...
...
@@ -452,6 +462,7 @@ enum change_attr_type4 {
#define FATTR4_WORD2_CHANGE_ATTR_TYPE (1UL << 15)
#define FATTR4_WORD2_SECURITY_LABEL (1UL << 16)
#define FATTR4_WORD2_MODE_UMASK (1UL << 17)
#define FATTR4_WORD2_XATTR_SUPPORT (1UL << 18)
/* MDS threshold bitmap bits */
#define THRESHOLD_RD (1UL << 0)
...
...
@@ -542,6 +553,11 @@ enum {
NFSPROC4_CLNT_LAYOUTERROR
,
NFSPROC4_CLNT_COPY_NOTIFY
,
NFSPROC4_CLNT_GETXATTR
,
NFSPROC4_CLNT_SETXATTR
,
NFSPROC4_CLNT_LISTXATTRS
,
NFSPROC4_CLNT_REMOVEXATTR
,
};
/* nfs41 types */
...
...
@@ -700,4 +716,13 @@ struct nl4_server {
struct
nfs42_netaddr
nl4_addr
;
/* NL4_NETADDR */
}
u
;
};
/*
* Options for setxattr. These match the flags for setxattr(2).
*/
enum
nfs4_setxattr_options
{
SETXATTR4_EITHER
=
0
,
SETXATTR4_CREATE
=
1
,
SETXATTR4_REPLACE
=
2
,
};
#endif
include/linux/nfs_fs.h
View file @
57f80c0e
...
...
@@ -102,6 +102,8 @@ struct nfs_delegation;
struct
posix_acl
;
struct
nfs4_xattr_cache
;
/*
* nfs fs inode data in memory
*/
...
...
@@ -188,6 +190,10 @@ struct nfs_inode {
struct
fscache_cookie
*
fscache
;
#endif
struct
inode
vfs_inode
;
#ifdef CONFIG_NFS_V4_2
struct
nfs4_xattr_cache
*
xattr_cache
;
#endif
};
struct
nfs4_copy_state
{
...
...
@@ -212,6 +218,9 @@ struct nfs4_copy_state {
#define NFS_ACCESS_EXTEND 0x0008
#define NFS_ACCESS_DELETE 0x0010
#define NFS_ACCESS_EXECUTE 0x0020
#define NFS_ACCESS_XAREAD 0x0040
#define NFS_ACCESS_XAWRITE 0x0080
#define NFS_ACCESS_XALIST 0x0100
/*
* Cache validity bit flags
...
...
@@ -231,6 +240,7 @@ struct nfs4_copy_state {
#define NFS_INO_DATA_INVAL_DEFER \
BIT(13)
/* Deferred cache invalidation */
#define NFS_INO_INVALID_BLOCKS BIT(14)
/* cached blocks are invalid */
#define NFS_INO_INVALID_XATTR BIT(15)
/* xattrs are invalid */
#define NFS_INO_INVALID_ATTR (NFS_INO_INVALID_CHANGE \
| NFS_INO_INVALID_CTIME \
...
...
@@ -490,6 +500,8 @@ extern int nfs_instantiate(struct dentry *dentry, struct nfs_fh *fh,
struct
nfs_fattr
*
fattr
,
struct
nfs4_label
*
label
);
extern
int
nfs_may_open
(
struct
inode
*
inode
,
const
struct
cred
*
cred
,
int
openflags
);
extern
void
nfs_access_zap_cache
(
struct
inode
*
inode
);
extern
int
nfs_access_get_cached
(
struct
inode
*
inode
,
const
struct
cred
*
cred
,
struct
nfs_access_entry
*
res
,
bool
may_block
);
/*
* linux/fs/nfs/symlink.c
...
...
include/linux/nfs_fs_sb.h
View file @
57f80c0e
...
...
@@ -163,6 +163,11 @@ struct nfs_server {
unsigned
int
dtsize
;
/* readdir size */
unsigned
short
port
;
/* "port=" setting */
unsigned
int
bsize
;
/* server block size */
#ifdef CONFIG_NFS_V4_2
unsigned
int
gxasize
;
/* getxattr size */
unsigned
int
sxasize
;
/* setxattr size */
unsigned
int
lxasize
;
/* listxattr size */
#endif
unsigned
int
acregmin
;
/* attr cache timeouts */
unsigned
int
acregmax
;
unsigned
int
acdirmin
;
...
...
@@ -281,5 +286,6 @@ struct nfs_server {
#define NFS_CAP_OFFLOAD_CANCEL (1U << 25)
#define NFS_CAP_LAYOUTERROR (1U << 26)
#define NFS_CAP_COPY_NOTIFY (1U << 27)
#define NFS_CAP_XATTR (1U << 28)
#endif
include/linux/nfs_xdr.h
View file @
57f80c0e
...
...
@@ -150,6 +150,7 @@ struct nfs_fsinfo {
__u32
layouttype
[
NFS_MAX_LAYOUT_TYPES
];
/* supported pnfs layout driver */
__u32
blksize
;
/* preferred pnfs io block size */
__u32
clone_blksize
;
/* granularity of a CLONE operation */
__u32
xattr_support
;
/* User xattrs supported */
};
struct
nfs_fsstat
{
...
...
@@ -1497,7 +1498,64 @@ struct nfs42_seek_res {
u32
sr_eof
;
u64
sr_offset
;
};
#endif
struct
nfs42_setxattrargs
{
struct
nfs4_sequence_args
seq_args
;
struct
nfs_fh
*
fh
;
const
char
*
xattr_name
;
u32
xattr_flags
;
size_t
xattr_len
;
struct
page
**
xattr_pages
;
};
struct
nfs42_setxattrres
{
struct
nfs4_sequence_res
seq_res
;
struct
nfs4_change_info
cinfo
;
};
struct
nfs42_getxattrargs
{
struct
nfs4_sequence_args
seq_args
;
struct
nfs_fh
*
fh
;
const
char
*
xattr_name
;
size_t
xattr_len
;
struct
page
**
xattr_pages
;
};
struct
nfs42_getxattrres
{
struct
nfs4_sequence_res
seq_res
;
size_t
xattr_len
;
};
struct
nfs42_listxattrsargs
{
struct
nfs4_sequence_args
seq_args
;
struct
nfs_fh
*
fh
;
u32
count
;
u64
cookie
;
struct
page
**
xattr_pages
;
};
struct
nfs42_listxattrsres
{
struct
nfs4_sequence_res
seq_res
;
struct
page
*
scratch
;
void
*
xattr_buf
;
size_t
xattr_len
;
u64
cookie
;
bool
eof
;
size_t
copied
;
};
struct
nfs42_removexattrargs
{
struct
nfs4_sequence_args
seq_args
;
struct
nfs_fh
*
fh
;
const
char
*
xattr_name
;
};
struct
nfs42_removexattrres
{
struct
nfs4_sequence_res
seq_res
;
struct
nfs4_change_info
cinfo
;
};
#endif
/* CONFIG_NFS_V4_2 */
struct
nfs_page
;
...
...
include/uapi/linux/nfs4.h
View file @
57f80c0e
...
...
@@ -33,6 +33,9 @@
#define NFS4_ACCESS_EXTEND 0x0008
#define NFS4_ACCESS_DELETE 0x0010
#define NFS4_ACCESS_EXECUTE 0x0020
#define NFS4_ACCESS_XAREAD 0x0040
#define NFS4_ACCESS_XAWRITE 0x0080
#define NFS4_ACCESS_XALIST 0x0100
#define NFS4_FH_PERSISTENT 0x0000
#define NFS4_FH_NOEXPIRE_WITH_OPEN 0x0001
...
...
include/uapi/linux/nfs_fs.h
View file @
57f80c0e
...
...
@@ -56,6 +56,7 @@
#define NFSDBG_PNFS 0x1000
#define NFSDBG_PNFS_LD 0x2000
#define NFSDBG_STATE 0x4000
#define NFSDBG_XATTRCACHE 0x8000
#define NFSDBG_ALL 0xFFFF
...
...
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