Skip to content

Commit 57f80c0

Browse files
author
Trond Myklebust
committed
Merge branch 'xattr-devel'
2 parents 18eb87f + 95ad37f commit 57f80c0

File tree

20 files changed

+2269
-42
lines changed

20 files changed

+2269
-42
lines changed

fs/nfs/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ nfsv4-y := nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o nfs4super.o nfs4file.o
3030
nfsv4-$(CONFIG_NFS_USE_LEGACY_DNS) += cache_lib.o
3131
nfsv4-$(CONFIG_SYSCTL) += nfs4sysctl.o
3232
nfsv4-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o pnfs_nfs.o
33-
nfsv4-$(CONFIG_NFS_V4_2) += nfs42proc.o
33+
nfsv4-$(CONFIG_NFS_V4_2) += nfs42proc.o nfs42xattr.o
3434

3535
obj-$(CONFIG_PNFS_FILE_LAYOUT) += filelayout/
3636
obj-$(CONFIG_PNFS_BLOCK) += blocklayout/

fs/nfs/client.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
#include "nfs.h"
5151
#include "netns.h"
5252
#include "sysfs.h"
53+
#include "nfs42.h"
5354

5455
#define NFSDBG_FACILITY NFSDBG_CLIENT
5556

@@ -749,7 +750,7 @@ static int nfs_init_server(struct nfs_server *server,
749750
static void nfs_server_set_fsinfo(struct nfs_server *server,
750751
struct nfs_fsinfo *fsinfo)
751752
{
752-
unsigned long max_rpc_payload;
753+
unsigned long max_rpc_payload, raw_max_rpc_payload;
753754

754755
/* Work out a lot of parameters */
755756
if (server->rsize == 0)
@@ -762,7 +763,9 @@ static void nfs_server_set_fsinfo(struct nfs_server *server,
762763
if (fsinfo->wtmax >= 512 && server->wsize > fsinfo->wtmax)
763764
server->wsize = nfs_block_size(fsinfo->wtmax, NULL);
764765

765-
max_rpc_payload = nfs_block_size(rpc_max_payload(server->client), NULL);
766+
raw_max_rpc_payload = rpc_max_payload(server->client);
767+
max_rpc_payload = nfs_block_size(raw_max_rpc_payload, NULL);
768+
766769
if (server->rsize > max_rpc_payload)
767770
server->rsize = max_rpc_payload;
768771
if (server->rsize > NFS_MAX_FILE_IO_SIZE)
@@ -795,6 +798,21 @@ static void nfs_server_set_fsinfo(struct nfs_server *server,
795798
server->clone_blksize = fsinfo->clone_blksize;
796799
/* We're airborne Set socket buffersize */
797800
rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100);
801+
802+
#ifdef CONFIG_NFS_V4_2
803+
/*
804+
* Defaults until limited by the session parameters.
805+
*/
806+
server->gxasize = min_t(unsigned int, raw_max_rpc_payload,
807+
XATTR_SIZE_MAX);
808+
server->sxasize = min_t(unsigned int, raw_max_rpc_payload,
809+
XATTR_SIZE_MAX);
810+
server->lxasize = min_t(unsigned int, raw_max_rpc_payload,
811+
nfs42_listxattr_xdrsize(XATTR_LIST_MAX));
812+
813+
if (fsinfo->xattr_support)
814+
server->caps |= NFS_CAP_XATTR;
815+
#endif
798816
}
799817

800818
/*

fs/nfs/dir.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2460,7 +2460,7 @@ static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, co
24602460
return NULL;
24612461
}
24622462

2463-
static int nfs_access_get_cached(struct inode *inode, const struct cred *cred, struct nfs_access_entry *res, bool may_block)
2463+
static int nfs_access_get_cached_locked(struct inode *inode, const struct cred *cred, struct nfs_access_entry *res, bool may_block)
24642464
{
24652465
struct nfs_inode *nfsi = NFS_I(inode);
24662466
struct nfs_access_entry *cache;
@@ -2533,6 +2533,20 @@ static int nfs_access_get_cached_rcu(struct inode *inode, const struct cred *cre
25332533
return err;
25342534
}
25352535

2536+
int nfs_access_get_cached(struct inode *inode, const struct cred *cred, struct
2537+
nfs_access_entry *res, bool may_block)
2538+
{
2539+
int status;
2540+
2541+
status = nfs_access_get_cached_rcu(inode, cred, res);
2542+
if (status != 0)
2543+
status = nfs_access_get_cached_locked(inode, cred, res,
2544+
may_block);
2545+
2546+
return status;
2547+
}
2548+
EXPORT_SYMBOL_GPL(nfs_access_get_cached);
2549+
25362550
static void nfs_access_add_rbtree(struct inode *inode, struct nfs_access_entry *set)
25372551
{
25382552
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)
26472661

26482662
trace_nfs_access_enter(inode);
26492663

2650-
status = nfs_access_get_cached_rcu(inode, cred, &cache);
2651-
if (status != 0)
2652-
status = nfs_access_get_cached(inode, cred, &cache, may_block);
2664+
status = nfs_access_get_cached(inode, cred, &cache, may_block);
26532665
if (status == 0)
26542666
goto out_cached;
26552667

@@ -2661,6 +2673,10 @@ static int nfs_do_access(struct inode *inode, const struct cred *cred, int mask)
26612673
* Determine which access bits we want to ask for...
26622674
*/
26632675
cache.mask = NFS_ACCESS_READ | NFS_ACCESS_MODIFY | NFS_ACCESS_EXTEND;
2676+
if (nfs_server_capable(inode, NFS_CAP_XATTR)) {
2677+
cache.mask |= NFS_ACCESS_XAREAD | NFS_ACCESS_XAWRITE |
2678+
NFS_ACCESS_XALIST;
2679+
}
26642680
if (S_ISDIR(inode->i_mode))
26652681
cache.mask |= NFS_ACCESS_DELETE | NFS_ACCESS_LOOKUP;
26662682
else

fs/nfs/inode.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ bool nfs_check_cache_invalid(struct inode *inode, unsigned long flags)
193193

194194
return nfs_check_cache_invalid_not_delegated(inode, flags);
195195
}
196+
EXPORT_SYMBOL_GPL(nfs_check_cache_invalid);
196197

197198
static void nfs_set_cache_invalid(struct inode *inode, unsigned long flags)
198199
{
@@ -204,7 +205,8 @@ static void nfs_set_cache_invalid(struct inode *inode, unsigned long flags)
204205
flags &= ~NFS_INO_INVALID_OTHER;
205206
flags &= ~(NFS_INO_INVALID_CHANGE
206207
| NFS_INO_INVALID_SIZE
207-
| NFS_INO_REVAL_PAGECACHE);
208+
| NFS_INO_REVAL_PAGECACHE
209+
| NFS_INO_INVALID_XATTR);
208210
}
209211

210212
if (inode->i_mapping->nrpages == 0)
@@ -233,11 +235,13 @@ static void nfs_zap_caches_locked(struct inode *inode)
233235
| NFS_INO_INVALID_DATA
234236
| NFS_INO_INVALID_ACCESS
235237
| NFS_INO_INVALID_ACL
238+
| NFS_INO_INVALID_XATTR
236239
| NFS_INO_REVAL_PAGECACHE);
237240
} else
238241
nfs_set_cache_invalid(inode, NFS_INO_INVALID_ATTR
239242
| NFS_INO_INVALID_ACCESS
240243
| NFS_INO_INVALID_ACL
244+
| NFS_INO_INVALID_XATTR
241245
| NFS_INO_REVAL_PAGECACHE);
242246
nfs_zap_label_cache_locked(nfsi);
243247
}
@@ -542,6 +546,8 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr, st
542546
inode->i_gid = fattr->gid;
543547
else if (nfs_server_capable(inode, NFS_CAP_OWNER_GROUP))
544548
nfs_set_cache_invalid(inode, NFS_INO_INVALID_OTHER);
549+
if (nfs_server_capable(inode, NFS_CAP_XATTR))
550+
nfs_set_cache_invalid(inode, NFS_INO_INVALID_XATTR);
545551
if (fattr->valid & NFS_ATTR_FATTR_BLOCKS_USED)
546552
inode->i_blocks = fattr->du.nfs2.blocks;
547553
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)
13771383
inode_set_iversion_raw(inode, fattr->change_attr);
13781384
if (S_ISDIR(inode->i_mode))
13791385
nfs_set_cache_invalid(inode, NFS_INO_INVALID_DATA);
1386+
else if (nfs_server_capable(inode, NFS_CAP_XATTR))
1387+
nfs_set_cache_invalid(inode, NFS_INO_INVALID_XATTR);
13801388
}
13811389
/* If we have atomic WCC data, we may update some attributes */
13821390
ts = inode->i_ctime;
@@ -1894,7 +1902,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
18941902
if (!(have_writers || have_delegation)) {
18951903
invalid |= NFS_INO_INVALID_DATA
18961904
| NFS_INO_INVALID_ACCESS
1897-
| NFS_INO_INVALID_ACL;
1905+
| NFS_INO_INVALID_ACL
1906+
| NFS_INO_INVALID_XATTR;
18981907
/* Force revalidate of all attributes */
18991908
save_cache_validity |= NFS_INO_INVALID_CTIME
19001909
| NFS_INO_INVALID_MTIME
@@ -2097,6 +2106,9 @@ struct inode *nfs_alloc_inode(struct super_block *sb)
20972106
#if IS_ENABLED(CONFIG_NFS_V4)
20982107
nfsi->nfs4_acl = NULL;
20992108
#endif /* CONFIG_NFS_V4 */
2109+
#ifdef CONFIG_NFS_V4_2
2110+
nfsi->xattr_cache = NULL;
2111+
#endif
21002112
return &nfsi->vfs_inode;
21012113
}
21022114
EXPORT_SYMBOL_GPL(nfs_alloc_inode);

fs/nfs/nfs42.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
#ifndef __LINUX_FS_NFS_NFS4_2_H
77
#define __LINUX_FS_NFS_NFS4_2_H
88

9+
#include <linux/xattr.h>
10+
911
/*
1012
* FIXME: four LAYOUTSTATS calls per compound at most! Do we need to support
1113
* 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,
3638
return nfs4_check_serverowner_major_id(c_in->cl_serverowner,
3739
c_out->cl_serverowner);
3840
}
41+
42+
ssize_t nfs42_proc_getxattr(struct inode *inode, const char *name,
43+
void *buf, size_t buflen);
44+
int nfs42_proc_setxattr(struct inode *inode, const char *name,
45+
const void *buf, size_t buflen, int flags);
46+
ssize_t nfs42_proc_listxattrs(struct inode *inode, void *buf,
47+
size_t buflen, u64 *cookiep, bool *eofp);
48+
int nfs42_proc_removexattr(struct inode *inode, const char *name);
49+
50+
/*
51+
* Maximum XDR buffer size needed for a listxattr buffer of buflen size.
52+
*
53+
* The upper boundary is a buffer with all 1-byte sized attribute names.
54+
* They would be 7 bytes long in the eventual buffer ("user.x\0"), and
55+
* 8 bytes long XDR-encoded.
56+
*
57+
* Include the trailing eof word as well.
58+
*/
59+
static inline u32 nfs42_listxattr_xdrsize(u32 buflen)
60+
{
61+
return ((buflen / (XATTR_USER_PREFIX_LEN + 2)) * 8) + 4;
62+
}
3963
#endif /* CONFIG_NFS_V4_2 */
4064
#endif /* __LINUX_FS_NFS_NFS4_2_H */

0 commit comments

Comments
 (0)