History

NFSv4: Honour the 'opened' parameter in the atomic_open() filesystem method

Determine if we've created a new file by examining the directory change attribute and/or the O_EXCL flag. This fixes a regression when doing a non-exclusive create of a new file. If the FILE_CREATED flag is not set, the atomic_open() command will perform full file access permissions checks instead of just checking for MAY_OPEN.

Trond Myklebust committed 13 years ago

Commit 5bc2afc1 parent 4a10c2a4 files · +24 −10Browse files

Unified · Split

4 files
  1. fs/nfs/dir.c +1 −1
  2. fs/nfs/nfs4file.c +2 −1
  3. fs/nfs/nfs4proc.c +19 −7
  4. include/linux/nfs_xdr.h +2 −1
fs/nfs/dir.c+1−1
@@ -1458,7 +1458,7 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry, · 1457 unmodified lines
14581458
14591459 trace_nfs_atomic_open_enter(dir, ctx, open_flags);
14601460 nfs_block_sillyrename(dentry->d_parent);
1461− inode = NFS_PROTO(dir)->open_context(dir, ctx, open_flags, &attr);
1461+ inode = NFS_PROTO(dir)->open_context(dir, ctx, open_flags, &attr, opened);
14621462 nfs_unblock_sillyrename(dentry->d_parent);
14631463 if (IS_ERR(inode)) {
14641464 err = PTR_ERR(inode);
fs/nfs/nfs4file.c+2−1
@@ -19,6 +19,7 @@ nfs4_file_open(struct inode *inode, struct file *filp) · 18 unmodified lines
1919 struct inode *dir;
2020 unsigned openflags = filp->f_flags;
2121 struct iattr attr;
22+ int opened = 0;
2223 int err;
2324
2425 /*
@@ -55,7 +56,7 @@ nfs4_file_open(struct inode *inode, struct file *filp) · 30 unmodified lines
5556 nfs_wb_all(inode);
5657 }
5758
58− inode = NFS_PROTO(dir)->open_context(dir, ctx, openflags, &attr);
59+ inode = NFS_PROTO(dir)->open_context(dir, ctx, openflags, &attr, &opened);
5960 if (IS_ERR(inode)) {
6061 err = PTR_ERR(inode);
6162 switch (err) {
fs/nfs/nfs4proc.c+19−7
@@ -912,6 +912,7 @@ struct nfs4_opendata { · 911 unmodified lines
912912 struct iattr attrs;
913913 unsigned long timestamp;
914914 unsigned int rpc_done : 1;
915+ unsigned int file_created : 1;
915916 unsigned int is_recover : 1;
916917 int rpc_status;
917918 int cancelled;
@@ -1946,8 +1947,13 @@ static int _nfs4_proc_open(struct nfs4_opendata *data) · 1028 unmodified lines
19461947
19471948 nfs_fattr_map_and_free_names(server, &data->f_attr);
19481949
1949− if (o_arg->open_flags & O_CREAT)
1950+ if (o_arg->open_flags & O_CREAT) {
19501951 update_changeattr(dir, &o_res->cinfo);
1952+ if (o_arg->open_flags & O_EXCL)
1953+ data->file_created = 1;
1954+ else if (o_res->cinfo.before != o_res->cinfo.after)
1955+ data->file_created = 1;
1956+ }
19511957 if ((o_res->rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) == 0)
19521958 server->caps &= ~NFS_CAP_POSIX_LOCK;
19531959 if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) {
@@ -2191,7 +2197,8 @@ static int _nfs4_do_open(struct inode *dir, · 237 unmodified lines
21912197 struct nfs_open_context *ctx,
21922198 int flags,
21932199 struct iattr *sattr,
2194− struct nfs4_label *label)
2200+ struct nfs4_label *label,
2201+ int *opened)
21952202 {
21962203 struct nfs4_state_owner *sp;
21972204 struct nfs4_state *state = NULL;
@@ -2261,6 +2268,8 @@ static int _nfs4_do_open(struct inode *dir, · 63 unmodified lines
22612268 nfs_setsecurity(state->inode, opendata->o_res.f_attr, olabel);
22622269 }
22632270 }
2271+ if (opendata->file_created)
2272+ *opened |= FILE_CREATED;
22642273
22652274 if (pnfs_use_threshold(ctx_th, opendata->f_attr.mdsthreshold, server))
22662275 *ctx_th = opendata->f_attr.mdsthreshold;
@@ -2289,7 +2298,8 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir, · 22 unmodified lines
22892298 struct nfs_open_context *ctx,
22902299 int flags,
22912300 struct iattr *sattr,
2292− struct nfs4_label *label)
2301+ struct nfs4_label *label,
2302+ int *opened)
22932303 {
22942304 struct nfs_server *server = NFS_SERVER(dir);
22952305 struct nfs4_exception exception = { };
@@ -2297,7 +2307,7 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir, · 1 unmodified line
22972307 int status;
22982308
22992309 do {
2300− status = _nfs4_do_open(dir, ctx, flags, sattr, label);
2310+ status = _nfs4_do_open(dir, ctx, flags, sattr, label, opened);
23012311 res = ctx->state;
23022312 trace_nfs4_open_file(ctx, flags, status);
23032313 if (status == 0)
@@ -2659,7 +2669,8 @@ out: · 355 unmodified lines
26592669 }
26602670
26612671 static struct inode *
2662−nfs4_atomic_open(struct inode *dir, struct nfs_open_context *ctx, int open_flags, struct iattr *attr)
2672+nfs4_atomic_open(struct inode *dir, struct nfs_open_context *ctx,
2673+ int open_flags, struct iattr *attr, int *opened)
26632674 {
26642675 struct nfs4_state *state;
26652676 struct nfs4_label l = {0, 0, 0, NULL}, *label = NULL;
@@ -2667,7 +2678,7 @@ nfs4_atomic_open(struct inode *dir, struct nfs_open_context *ctx, int open_flags · 1 unmodified line
26672678 label = nfs4_label_init_security(dir, ctx->dentry, attr, &l);
26682679
26692680 /* Protect against concurrent sillydeletes */
2670− state = nfs4_do_open(dir, ctx, open_flags, attr, label);
2681+ state = nfs4_do_open(dir, ctx, open_flags, attr, label, opened);
26712682
26722683 nfs4_label_release_security(label);
26732684
@@ -3332,6 +3343,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, · 658 unmodified lines
33323343 struct nfs4_label l, *ilabel = NULL;
33333344 struct nfs_open_context *ctx;
33343345 struct nfs4_state *state;
3346+ int opened = 0;
33353347 int status = 0;
33363348
33373349 ctx = alloc_nfs_open_context(dentry, FMODE_READ);
@@ -3341,7 +3353,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, · 3 unmodified lines
33413353 ilabel = nfs4_label_init_security(dir, dentry, sattr, &l);
33423354
33433355 sattr->ia_mode &= ~current_umask();
3344− state = nfs4_do_open(dir, ctx, flags, sattr, ilabel);
3356+ state = nfs4_do_open(dir, ctx, flags, sattr, ilabel, &opened);
33453357 if (IS_ERR(state)) {
33463358 status = PTR_ERR(state);
33473359 goto out;
include/linux/nfs_xdr.h+2−1
@@ -1455,7 +1455,8 @@ struct nfs_rpc_ops { · 1454 unmodified lines
14551455 struct inode * (*open_context) (struct inode *dir,
14561456 struct nfs_open_context *ctx,
14571457 int open_flags,
1458− struct iattr *iattr);
1458+ struct iattr *iattr,
1459+ int *);
14591460 int (*have_delegation)(struct inode *, fmode_t);
14601461 int (*return_delegation)(struct inode *);
14611462 struct nfs_client *(*alloc_client) (const struct nfs_client_initdata *);

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t