There have been reports of races that cause NFSv4 OPEN(CREATE) to return an error even though the requested file was created. NFSv4 does not provide a status code for this case. To mitigate some of these problems, reorganize the NFSv4 OPEN(CREATE) logic to allocate resources before the file is actually created, and open the new file while the parent directory is still locked. Two new APIs are added: + Add an API that works like nfsd_file_acquire() but does not open the underlying file. The OPEN(CREATE) path can use this API when it already has an open file. + Add an API that is kin to dentry_open(). NFSD needs to create a file and grab an open "struct file *" atomically. The alloc_empty_file() has to be done before the inode create. If it fails (for example, because the NFS server has exceeded its max_files limit), we avoid creating the file and can still return an error to the NFS client.
Showing the changes to include (1 of 7 files). Show all
Unified · Split
| @@ -2640,6 +2640,8 @@ static inline struct file *file_open_root_mnt(struct vfsmount *mnt, · 2639 unmodified lines | ||
| 2640 | 2640 | name, flags, mode); |
| 2641 | 2641 | } |
| 2642 | 2642 | extern struct file * dentry_open(const struct path *, int, const struct cred *); |
| 2643 | +extern struct file *dentry_create(const struct path *path, int flags, | |
| 2644 | + umode_t mode, const struct cred *cred); | |
| 2643 | 2645 | extern struct file * open_with_fake_path(const struct path *, int, |
| 2644 | 2646 | struct inode*, const struct cred *); |
| 2645 | 2647 | static inline struct file *file_clone_open(struct file *file) |