| @@ -912,6 +912,7 @@ struct nfs4_opendata { · 911 unmodified lines |
| 912 | 912 | struct iattr attrs; |
| 913 | 913 | unsigned long timestamp; |
| 914 | 914 | unsigned int rpc_done : 1; |
| 915 | + unsigned int file_created : 1; |
| 915 | 916 | unsigned int is_recover : 1; |
| 916 | 917 | int rpc_status; |
| 917 | 918 | int cancelled; |
| @@ -1946,8 +1947,13 @@ static int _nfs4_proc_open(struct nfs4_opendata *data) · 1028 unmodified lines |
| 1946 | 1947 | |
| 1947 | 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 | 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 | 1957 | if ((o_res->rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) == 0) |
| 1952 | 1958 | server->caps &= ~NFS_CAP_POSIX_LOCK; |
| 1953 | 1959 | if(o_res->rflags & NFS4_OPEN_RESULT_CONFIRM) { |
| @@ -2191,7 +2197,8 @@ static int _nfs4_do_open(struct inode *dir, · 237 unmodified lines |
| 2191 | 2197 | struct nfs_open_context *ctx, |
| 2192 | 2198 | int flags, |
| 2193 | 2199 | struct iattr *sattr, |
| 2194 | | − struct nfs4_label *label) |
| 2200 | + struct nfs4_label *label, |
| 2201 | + int *opened) |
| 2195 | 2202 | { |
| 2196 | 2203 | struct nfs4_state_owner *sp; |
| 2197 | 2204 | struct nfs4_state *state = NULL; |
| @@ -2261,6 +2268,8 @@ static int _nfs4_do_open(struct inode *dir, · 63 unmodified lines |
| 2261 | 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 | 2274 | if (pnfs_use_threshold(ctx_th, opendata->f_attr.mdsthreshold, server)) |
| 2266 | 2275 | *ctx_th = opendata->f_attr.mdsthreshold; |
| @@ -2289,7 +2298,8 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir, · 22 unmodified lines |
| 2289 | 2298 | struct nfs_open_context *ctx, |
| 2290 | 2299 | int flags, |
| 2291 | 2300 | struct iattr *sattr, |
| 2292 | | − struct nfs4_label *label) |
| 2301 | + struct nfs4_label *label, |
| 2302 | + int *opened) |
| 2293 | 2303 | { |
| 2294 | 2304 | struct nfs_server *server = NFS_SERVER(dir); |
| 2295 | 2305 | struct nfs4_exception exception = { }; |
| @@ -2297,7 +2307,7 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir, · 1 unmodified line |
| 2297 | 2307 | int status; |
| 2298 | 2308 | |
| 2299 | 2309 | do { |
| 2300 | | − status = _nfs4_do_open(dir, ctx, flags, sattr, label); |
| 2310 | + status = _nfs4_do_open(dir, ctx, flags, sattr, label, opened); |
| 2301 | 2311 | res = ctx->state; |
| 2302 | 2312 | trace_nfs4_open_file(ctx, flags, status); |
| 2303 | 2313 | if (status == 0) |
| @@ -2659,7 +2669,8 @@ out: · 355 unmodified lines |
| 2659 | 2669 | } |
| 2660 | 2670 | |
| 2661 | 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 | 2675 | struct nfs4_state *state; |
| 2665 | 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 · 1 unmodified line |
| 2667 | 2678 | label = nfs4_label_init_security(dir, ctx->dentry, attr, &l); |
| 2668 | 2679 | |
| 2669 | 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 | 2683 | nfs4_label_release_security(label); |
| 2673 | 2684 | |
| @@ -3332,6 +3343,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, · 658 unmodified lines |
| 3332 | 3343 | struct nfs4_label l, *ilabel = NULL; |
| 3333 | 3344 | struct nfs_open_context *ctx; |
| 3334 | 3345 | struct nfs4_state *state; |
| 3346 | + int opened = 0; |
| 3335 | 3347 | int status = 0; |
| 3336 | 3348 | |
| 3337 | 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, · 3 unmodified lines |
| 3341 | 3353 | ilabel = nfs4_label_init_security(dir, dentry, sattr, &l); |
| 3342 | 3354 | |
| 3343 | 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 | 3357 | if (IS_ERR(state)) { |
| 3346 | 3358 | status = PTR_ERR(state); |
| 3347 | 3359 | goto out; |