Skip to content

Commit 1b523ca

Browse files
fllindenTrond Myklebust
authored andcommitted
nfs: modify update_changeattr to deal with regular files
Until now, change attributes in change_info form were only returned by directory operations. However, they are also used for the RFC 8276 extended attribute operations, which work on both directories and regular files. Modify update_changeattr to deal: * Rename it to nfs4_update_changeattr and make it non-static. * Don't always use INO_INVALID_DATA, this isn't needed for a directory that only had its extended attributes changed by us. * Existing callers now always pass in INO_INVALID_DATA. For the current callers of this function, behavior is unchanged. Signed-off-by: Frank van der Linden <[email protected]> Signed-off-by: Trond Myklebust <[email protected]>
1 parent 72832a2 commit 1b523ca

File tree

2 files changed

+49
-26
lines changed

2 files changed

+49
-26
lines changed

fs/nfs/nfs4_fs.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,11 @@ extern int update_open_stateid(struct nfs4_state *state,
324324

325325
extern int nfs4_proc_get_lease_time(struct nfs_client *clp,
326326
struct nfs_fsinfo *fsinfo);
327+
extern void nfs4_update_changeattr(struct inode *dir,
328+
struct nfs4_change_info *cinfo,
329+
unsigned long timestamp,
330+
unsigned long cache_validity);
331+
327332
#if defined(CONFIG_NFS_V4_1)
328333
extern int nfs41_sequence_done(struct rpc_task *, struct nfs4_sequence_res *);
329334
extern int nfs4_proc_create_session(struct nfs_client *, const struct cred *);

fs/nfs/nfs4proc.c

Lines changed: 44 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1158,37 +1158,48 @@ nfs4_dec_nlink_locked(struct inode *inode)
11581158
}
11591159

11601160
static void
1161-
update_changeattr_locked(struct inode *dir, struct nfs4_change_info *cinfo,
1161+
nfs4_update_changeattr_locked(struct inode *inode,
1162+
struct nfs4_change_info *cinfo,
11621163
unsigned long timestamp, unsigned long cache_validity)
11631164
{
1164-
struct nfs_inode *nfsi = NFS_I(dir);
1165+
struct nfs_inode *nfsi = NFS_I(inode);
11651166

11661167
nfsi->cache_validity |= NFS_INO_INVALID_CTIME
11671168
| NFS_INO_INVALID_MTIME
1168-
| NFS_INO_INVALID_DATA
11691169
| cache_validity;
1170-
if (cinfo->atomic && cinfo->before == inode_peek_iversion_raw(dir)) {
1170+
1171+
if (cinfo->atomic && cinfo->before == inode_peek_iversion_raw(inode)) {
11711172
nfsi->cache_validity &= ~NFS_INO_REVAL_PAGECACHE;
11721173
nfsi->attrtimeo_timestamp = jiffies;
11731174
} else {
1174-
nfs_force_lookup_revalidate(dir);
1175-
if (cinfo->before != inode_peek_iversion_raw(dir))
1175+
if (S_ISDIR(inode->i_mode)) {
1176+
nfsi->cache_validity |= NFS_INO_INVALID_DATA;
1177+
nfs_force_lookup_revalidate(inode);
1178+
} else {
1179+
if (!NFS_PROTO(inode)->have_delegation(inode,
1180+
FMODE_READ))
1181+
nfsi->cache_validity |= NFS_INO_REVAL_PAGECACHE;
1182+
}
1183+
1184+
if (cinfo->before != inode_peek_iversion_raw(inode))
11761185
nfsi->cache_validity |= NFS_INO_INVALID_ACCESS |
1177-
NFS_INO_INVALID_ACL;
1186+
NFS_INO_INVALID_ACL;
11781187
}
1179-
inode_set_iversion_raw(dir, cinfo->after);
1188+
inode_set_iversion_raw(inode, cinfo->after);
11801189
nfsi->read_cache_jiffies = timestamp;
11811190
nfsi->attr_gencount = nfs_inc_attr_generation_counter();
11821191
nfsi->cache_validity &= ~NFS_INO_INVALID_CHANGE;
1183-
nfs_fscache_invalidate(dir);
1192+
1193+
if (nfsi->cache_validity & NFS_INO_INVALID_DATA)
1194+
nfs_fscache_invalidate(inode);
11841195
}
11851196

1186-
static void
1187-
update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo,
1197+
void
1198+
nfs4_update_changeattr(struct inode *dir, struct nfs4_change_info *cinfo,
11881199
unsigned long timestamp, unsigned long cache_validity)
11891200
{
11901201
spin_lock(&dir->i_lock);
1191-
update_changeattr_locked(dir, cinfo, timestamp, cache_validity);
1202+
nfs4_update_changeattr_locked(dir, cinfo, timestamp, cache_validity);
11921203
spin_unlock(&dir->i_lock);
11931204
}
11941205

@@ -2644,8 +2655,9 @@ static int _nfs4_proc_open(struct nfs4_opendata *data,
26442655
data->file_created = true;
26452656
if (data->file_created ||
26462657
inode_peek_iversion_raw(dir) != o_res->cinfo.after)
2647-
update_changeattr(dir, &o_res->cinfo,
2648-
o_res->f_attr->time_start, 0);
2658+
nfs4_update_changeattr(dir, &o_res->cinfo,
2659+
o_res->f_attr->time_start,
2660+
NFS_INO_INVALID_DATA);
26492661
}
26502662
if ((o_res->rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) == 0)
26512663
server->caps &= ~NFS_CAP_POSIX_LOCK;
@@ -4531,7 +4543,8 @@ _nfs4_proc_remove(struct inode *dir, const struct qstr *name, u32 ftype)
45314543
status = nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 1);
45324544
if (status == 0) {
45334545
spin_lock(&dir->i_lock);
4534-
update_changeattr_locked(dir, &res.cinfo, timestamp, 0);
4546+
nfs4_update_changeattr_locked(dir, &res.cinfo, timestamp,
4547+
NFS_INO_INVALID_DATA);
45354548
/* Removing a directory decrements nlink in the parent */
45364549
if (ftype == NF4DIR && dir->i_nlink > 2)
45374550
nfs4_dec_nlink_locked(dir);
@@ -4615,8 +4628,9 @@ static int nfs4_proc_unlink_done(struct rpc_task *task, struct inode *dir)
46154628
&data->timeout) == -EAGAIN)
46164629
return 0;
46174630
if (task->tk_status == 0)
4618-
update_changeattr(dir, &res->cinfo,
4619-
res->dir_attr->time_start, 0);
4631+
nfs4_update_changeattr(dir, &res->cinfo,
4632+
res->dir_attr->time_start,
4633+
NFS_INO_INVALID_DATA);
46204634
return 1;
46214635
}
46224636

@@ -4660,16 +4674,18 @@ static int nfs4_proc_rename_done(struct rpc_task *task, struct inode *old_dir,
46604674
if (task->tk_status == 0) {
46614675
if (new_dir != old_dir) {
46624676
/* Note: If we moved a directory, nlink will change */
4663-
update_changeattr(old_dir, &res->old_cinfo,
4677+
nfs4_update_changeattr(old_dir, &res->old_cinfo,
46644678
res->old_fattr->time_start,
4665-
NFS_INO_INVALID_OTHER);
4666-
update_changeattr(new_dir, &res->new_cinfo,
4679+
NFS_INO_INVALID_OTHER |
4680+
NFS_INO_INVALID_DATA);
4681+
nfs4_update_changeattr(new_dir, &res->new_cinfo,
46674682
res->new_fattr->time_start,
4668-
NFS_INO_INVALID_OTHER);
4683+
NFS_INO_INVALID_OTHER |
4684+
NFS_INO_INVALID_DATA);
46694685
} else
4670-
update_changeattr(old_dir, &res->old_cinfo,
4686+
nfs4_update_changeattr(old_dir, &res->old_cinfo,
46714687
res->old_fattr->time_start,
4672-
0);
4688+
NFS_INO_INVALID_DATA);
46734689
}
46744690
return 1;
46754691
}
@@ -4710,7 +4726,8 @@ static int _nfs4_proc_link(struct inode *inode, struct inode *dir, const struct
47104726

47114727
status = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
47124728
if (!status) {
4713-
update_changeattr(dir, &res.cinfo, res.fattr->time_start, 0);
4729+
nfs4_update_changeattr(dir, &res.cinfo, res.fattr->time_start,
4730+
NFS_INO_INVALID_DATA);
47144731
status = nfs_post_op_update_inode(inode, res.fattr);
47154732
if (!status)
47164733
nfs_setsecurity(inode, res.fattr, res.label);
@@ -4788,8 +4805,9 @@ static int nfs4_do_create(struct inode *dir, struct dentry *dentry, struct nfs4_
47884805
&data->arg.seq_args, &data->res.seq_res, 1);
47894806
if (status == 0) {
47904807
spin_lock(&dir->i_lock);
4791-
update_changeattr_locked(dir, &data->res.dir_cinfo,
4792-
data->res.fattr->time_start, 0);
4808+
nfs4_update_changeattr_locked(dir, &data->res.dir_cinfo,
4809+
data->res.fattr->time_start,
4810+
NFS_INO_INVALID_DATA);
47934811
/* Creating a directory bumps nlink in the parent */
47944812
if (data->arg.ftype == NF4DIR)
47954813
nfs4_inc_nlink_locked(dir);

0 commit comments

Comments
 (0)