diff options
-rw-r--r-- | fs/nfs/dir.c | 2 | ||||
-rw-r--r-- | fs/nfs/nfs4file.c | 3 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 26 | ||||
-rw-r--r-- | include/linux/nfs_xdr.h | 3 |
4 files changed, 24 insertions, 10 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 854a8f05a610..02b0df769e2d 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -1458,7 +1458,7 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry, | |||
1458 | 1458 | ||
1459 | trace_nfs_atomic_open_enter(dir, ctx, open_flags); | 1459 | trace_nfs_atomic_open_enter(dir, ctx, open_flags); |
1460 | nfs_block_sillyrename(dentry->d_parent); | 1460 | 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); |
1462 | nfs_unblock_sillyrename(dentry->d_parent); | 1462 | nfs_unblock_sillyrename(dentry->d_parent); |
1463 | if (IS_ERR(inode)) { | 1463 | if (IS_ERR(inode)) { |
1464 | err = PTR_ERR(inode); | 1464 | err = PTR_ERR(inode); |
diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c index e5b804dd944c..77efaf15ec90 100644 --- a/fs/nfs/nfs4file.c +++ b/fs/nfs/nfs4file.c | |||
@@ -19,6 +19,7 @@ nfs4_file_open(struct inode *inode, struct file *filp) | |||
19 | struct inode *dir; | 19 | struct inode *dir; |
20 | unsigned openflags = filp->f_flags; | 20 | unsigned openflags = filp->f_flags; |
21 | struct iattr attr; | 21 | struct iattr attr; |
22 | int opened = 0; | ||
22 | int err; | 23 | int err; |
23 | 24 | ||
24 | /* | 25 | /* |
@@ -55,7 +56,7 @@ nfs4_file_open(struct inode *inode, struct file *filp) | |||
55 | nfs_wb_all(inode); | 56 | nfs_wb_all(inode); |
56 | } | 57 | } |
57 | 58 | ||
58 | inode = NFS_PROTO(dir)->open_context(dir, ctx, openflags, &attr); | 59 | inode = NFS_PROTO(dir)->open_context(dir, ctx, openflags, &attr, &opened); |
59 | if (IS_ERR(inode)) { | 60 | if (IS_ERR(inode)) { |
60 | err = PTR_ERR(inode); | 61 | err = PTR_ERR(inode); |
61 | switch (err) { | 62 | switch (err) { |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 989bb9d3074d..488ef9b5c51a 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -912,6 +912,7 @@ struct nfs4_opendata { | |||
912 | struct iattr attrs; | 912 | struct iattr attrs; |
913 | unsigned long timestamp; | 913 | unsigned long timestamp; |
914 | unsigned int rpc_done : 1; | 914 | unsigned int rpc_done : 1; |
915 | unsigned int file_created : 1; | ||
915 | unsigned int is_recover : 1; | 916 | unsigned int is_recover : 1; |
916 | int rpc_status; | 917 | int rpc_status; |
917 | int cancelled; | 918 | int cancelled; |
@@ -1946,8 +1947,13 @@ static int _nfs4_proc_open(struct nfs4_opendata *data) | |||
1946 | 1947 | ||
1947 | nfs_fattr_map_and_free_names(server, &data->f_attr); | 1948 | nfs_fattr_map_and_free_names(server, &data->f_attr); |
1948 | 1949 | ||
1949 | if (o_arg->open_flags & O_CREAT) | 1950 | if (o_arg->open_flags & O_CREAT) { |
1950 | update_changeattr(dir, &o_res->cinfo); | 1951 | 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 | } | ||
1951 | if ((o_res->rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) == 0) | 1957 | if ((o_res->rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) == 0) |
1952 | server->caps &= ~NFS_CAP_POSIX_LOCK; | 1958 | server->caps &= ~NFS_CAP_POSIX_LOCK; |
1953 | if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) { | 1959 | if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) { |
@@ -2191,7 +2197,8 @@ static int _nfs4_do_open(struct inode *dir, | |||
2191 | struct nfs_open_context *ctx, | 2197 | struct nfs_open_context *ctx, |
2192 | int flags, | 2198 | int flags, |
2193 | struct iattr *sattr, | 2199 | struct iattr *sattr, |
2194 | struct nfs4_label *label) | 2200 | struct nfs4_label *label, |
2201 | int *opened) | ||
2195 | { | 2202 | { |
2196 | struct nfs4_state_owner *sp; | 2203 | struct nfs4_state_owner *sp; |
2197 | struct nfs4_state *state = NULL; | 2204 | struct nfs4_state *state = NULL; |
@@ -2261,6 +2268,8 @@ static int _nfs4_do_open(struct inode *dir, | |||
2261 | nfs_setsecurity(state->inode, opendata->o_res.f_attr, olabel); | 2268 | nfs_setsecurity(state->inode, opendata->o_res.f_attr, olabel); |
2262 | } | 2269 | } |
2263 | } | 2270 | } |
2271 | if (opendata->file_created) | ||
2272 | *opened |= FILE_CREATED; | ||
2264 | 2273 | ||
2265 | if (pnfs_use_threshold(ctx_th, opendata->f_attr.mdsthreshold, server)) | 2274 | if (pnfs_use_threshold(ctx_th, opendata->f_attr.mdsthreshold, server)) |
2266 | *ctx_th = opendata->f_attr.mdsthreshold; | 2275 | *ctx_th = opendata->f_attr.mdsthreshold; |
@@ -2289,7 +2298,8 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir, | |||
2289 | struct nfs_open_context *ctx, | 2298 | struct nfs_open_context *ctx, |
2290 | int flags, | 2299 | int flags, |
2291 | struct iattr *sattr, | 2300 | struct iattr *sattr, |
2292 | struct nfs4_label *label) | 2301 | struct nfs4_label *label, |
2302 | int *opened) | ||
2293 | { | 2303 | { |
2294 | struct nfs_server *server = NFS_SERVER(dir); | 2304 | struct nfs_server *server = NFS_SERVER(dir); |
2295 | struct nfs4_exception exception = { }; | 2305 | struct nfs4_exception exception = { }; |
@@ -2297,7 +2307,7 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir, | |||
2297 | int status; | 2307 | int status; |
2298 | 2308 | ||
2299 | do { | 2309 | do { |
2300 | status = _nfs4_do_open(dir, ctx, flags, sattr, label); | 2310 | status = _nfs4_do_open(dir, ctx, flags, sattr, label, opened); |
2301 | res = ctx->state; | 2311 | res = ctx->state; |
2302 | trace_nfs4_open_file(ctx, flags, status); | 2312 | trace_nfs4_open_file(ctx, flags, status); |
2303 | if (status == 0) | 2313 | if (status == 0) |
@@ -2659,7 +2669,8 @@ out: | |||
2659 | } | 2669 | } |
2660 | 2670 | ||
2661 | static struct inode * | 2671 | 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) | ||
2663 | { | 2674 | { |
2664 | struct nfs4_state *state; | 2675 | struct nfs4_state *state; |
2665 | struct nfs4_label l = {0, 0, 0, NULL}, *label = NULL; | 2676 | 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 | |||
2667 | label = nfs4_label_init_security(dir, ctx->dentry, attr, &l); | 2678 | label = nfs4_label_init_security(dir, ctx->dentry, attr, &l); |
2668 | 2679 | ||
2669 | /* Protect against concurrent sillydeletes */ | 2680 | /* 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); |
2671 | 2682 | ||
2672 | nfs4_label_release_security(label); | 2683 | nfs4_label_release_security(label); |
2673 | 2684 | ||
@@ -3332,6 +3343,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | |||
3332 | struct nfs4_label l, *ilabel = NULL; | 3343 | struct nfs4_label l, *ilabel = NULL; |
3333 | struct nfs_open_context *ctx; | 3344 | struct nfs_open_context *ctx; |
3334 | struct nfs4_state *state; | 3345 | struct nfs4_state *state; |
3346 | int opened = 0; | ||
3335 | int status = 0; | 3347 | int status = 0; |
3336 | 3348 | ||
3337 | ctx = alloc_nfs_open_context(dentry, FMODE_READ); | 3349 | ctx = alloc_nfs_open_context(dentry, FMODE_READ); |
@@ -3341,7 +3353,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | |||
3341 | ilabel = nfs4_label_init_security(dir, dentry, sattr, &l); | 3353 | ilabel = nfs4_label_init_security(dir, dentry, sattr, &l); |
3342 | 3354 | ||
3343 | sattr->ia_mode &= ~current_umask(); | 3355 | 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); |
3345 | if (IS_ERR(state)) { | 3357 | if (IS_ERR(state)) { |
3346 | status = PTR_ERR(state); | 3358 | status = PTR_ERR(state); |
3347 | goto out; | 3359 | goto out; |
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 01fd84b566f7..49f52c8f4422 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
@@ -1455,7 +1455,8 @@ struct nfs_rpc_ops { | |||
1455 | struct inode * (*open_context) (struct inode *dir, | 1455 | struct inode * (*open_context) (struct inode *dir, |
1456 | struct nfs_open_context *ctx, | 1456 | struct nfs_open_context *ctx, |
1457 | int open_flags, | 1457 | int open_flags, |
1458 | struct iattr *iattr); | 1458 | struct iattr *iattr, |
1459 | int *); | ||
1459 | int (*have_delegation)(struct inode *, fmode_t); | 1460 | int (*have_delegation)(struct inode *, fmode_t); |
1460 | int (*return_delegation)(struct inode *); | 1461 | int (*return_delegation)(struct inode *); |
1461 | struct nfs_client *(*alloc_client) (const struct nfs_client_initdata *); | 1462 | struct nfs_client *(*alloc_client) (const struct nfs_client_initdata *); |