kill struct opendata
Just pass struct file *. Methods are happier that way... There's no need to return struct file * from finish_open() now, so let it return int. Next: saner prototypes for parts in namei.c Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
a4a3bdd778
commit
30d9049474
15 changed files with 81 additions and 98 deletions
|
@ -63,7 +63,7 @@ ata *);
|
||||||
int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len);
|
int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len);
|
||||||
void (*update_time)(struct inode *, struct timespec *, int);
|
void (*update_time)(struct inode *, struct timespec *, int);
|
||||||
int (*atomic_open)(struct inode *, struct dentry *,
|
int (*atomic_open)(struct inode *, struct dentry *,
|
||||||
struct opendata *, unsigned open_flag,
|
struct file *, unsigned open_flag,
|
||||||
umode_t create_mode, int *opened);
|
umode_t create_mode, int *opened);
|
||||||
|
|
||||||
locking rules:
|
locking rules:
|
||||||
|
|
|
@ -365,7 +365,7 @@ struct inode_operations {
|
||||||
int (*removexattr) (struct dentry *, const char *);
|
int (*removexattr) (struct dentry *, const char *);
|
||||||
void (*update_time)(struct inode *, struct timespec *, int);
|
void (*update_time)(struct inode *, struct timespec *, int);
|
||||||
int (*atomic_open)(struct inode *, struct dentry *,
|
int (*atomic_open)(struct inode *, struct dentry *,
|
||||||
struct opendata *, unsigned open_flag,
|
struct file *, unsigned open_flag,
|
||||||
umode_t create_mode, int *opened);
|
umode_t create_mode, int *opened);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -858,12 +858,11 @@ struct dentry *v9fs_vfs_lookup(struct inode *dir, struct dentry *dentry,
|
||||||
|
|
||||||
static int
|
static int
|
||||||
v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
|
v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
|
||||||
struct opendata *od, unsigned flags, umode_t mode,
|
struct file *file, unsigned flags, umode_t mode,
|
||||||
int *opened)
|
int *opened)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
u32 perm;
|
u32 perm;
|
||||||
struct file *filp;
|
|
||||||
struct v9fs_inode *v9inode;
|
struct v9fs_inode *v9inode;
|
||||||
struct v9fs_session_info *v9ses;
|
struct v9fs_session_info *v9ses;
|
||||||
struct p9_fid *fid, *inode_fid;
|
struct p9_fid *fid, *inode_fid;
|
||||||
|
@ -880,7 +879,7 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
|
||||||
|
|
||||||
/* Only creates */
|
/* Only creates */
|
||||||
if (!(flags & O_CREAT) || dentry->d_inode) {
|
if (!(flags & O_CREAT) || dentry->d_inode) {
|
||||||
finish_no_open(od, res);
|
finish_no_open(file, res);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -918,16 +917,14 @@ v9fs_vfs_atomic_open(struct inode *dir, struct dentry *dentry,
|
||||||
v9inode->writeback_fid = (void *) inode_fid;
|
v9inode->writeback_fid = (void *) inode_fid;
|
||||||
}
|
}
|
||||||
mutex_unlock(&v9inode->v_mutex);
|
mutex_unlock(&v9inode->v_mutex);
|
||||||
filp = finish_open(od, dentry, generic_file_open, opened);
|
err = finish_open(file, dentry, generic_file_open, opened);
|
||||||
if (IS_ERR(filp)) {
|
if (err)
|
||||||
err = PTR_ERR(filp);
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
|
|
||||||
filp->private_data = fid;
|
file->private_data = fid;
|
||||||
#ifdef CONFIG_9P_FSCACHE
|
#ifdef CONFIG_9P_FSCACHE
|
||||||
if (v9ses->cache)
|
if (v9ses->cache)
|
||||||
v9fs_cache_inode_set_cookie(dentry->d_inode, filp);
|
v9fs_cache_inode_set_cookie(dentry->d_inode, file);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
*opened |= FILE_CREATED;
|
*opened |= FILE_CREATED;
|
||||||
|
|
|
@ -242,14 +242,13 @@ v9fs_vfs_create_dotl(struct inode *dir, struct dentry *dentry, umode_t omode,
|
||||||
|
|
||||||
static int
|
static int
|
||||||
v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
|
v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
|
||||||
struct opendata *od, unsigned flags, umode_t omode,
|
struct file *file, unsigned flags, umode_t omode,
|
||||||
int *opened)
|
int *opened)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
gid_t gid;
|
gid_t gid;
|
||||||
umode_t mode;
|
umode_t mode;
|
||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
struct file *filp;
|
|
||||||
struct p9_qid qid;
|
struct p9_qid qid;
|
||||||
struct inode *inode;
|
struct inode *inode;
|
||||||
struct p9_fid *fid = NULL;
|
struct p9_fid *fid = NULL;
|
||||||
|
@ -270,7 +269,7 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
|
||||||
|
|
||||||
/* Only creates */
|
/* Only creates */
|
||||||
if (!(flags & O_CREAT) || dentry->d_inode) {
|
if (!(flags & O_CREAT) || dentry->d_inode) {
|
||||||
finish_no_open(od, res);
|
finish_no_open(file, res);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,15 +356,13 @@ v9fs_vfs_atomic_open_dotl(struct inode *dir, struct dentry *dentry,
|
||||||
}
|
}
|
||||||
mutex_unlock(&v9inode->v_mutex);
|
mutex_unlock(&v9inode->v_mutex);
|
||||||
/* Since we are opening a file, assign the open fid to the file */
|
/* Since we are opening a file, assign the open fid to the file */
|
||||||
filp = finish_open(od, dentry, generic_file_open, opened);
|
err = finish_open(file, dentry, generic_file_open, opened);
|
||||||
if (IS_ERR(filp)) {
|
if (err)
|
||||||
err = PTR_ERR(filp);
|
|
||||||
goto err_clunk_old_fid;
|
goto err_clunk_old_fid;
|
||||||
}
|
file->private_data = ofid;
|
||||||
filp->private_data = ofid;
|
|
||||||
#ifdef CONFIG_9P_FSCACHE
|
#ifdef CONFIG_9P_FSCACHE
|
||||||
if (v9ses->cache)
|
if (v9ses->cache)
|
||||||
v9fs_cache_inode_set_cookie(inode, filp);
|
v9fs_cache_inode_set_cookie(inode, file);
|
||||||
#endif
|
#endif
|
||||||
*opened |= FILE_CREATED;
|
*opened |= FILE_CREATED;
|
||||||
out:
|
out:
|
||||||
|
|
|
@ -635,7 +635,7 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry,
|
||||||
}
|
}
|
||||||
|
|
||||||
int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
|
int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
|
||||||
struct opendata *od, unsigned flags, umode_t mode,
|
struct file *file, unsigned flags, umode_t mode,
|
||||||
int *opened)
|
int *opened)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
@ -649,7 +649,7 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
return ceph_lookup_open(dir, dentry, od, flags, mode, opened);
|
return ceph_lookup_open(dir, dentry, file, flags, mode, opened);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d_unhashed(dentry)) {
|
if (d_unhashed(dentry)) {
|
||||||
|
@ -663,12 +663,12 @@ int ceph_atomic_open(struct inode *dir, struct dentry *dentry,
|
||||||
|
|
||||||
/* We don't deal with positive dentries here */
|
/* We don't deal with positive dentries here */
|
||||||
if (dentry->d_inode) {
|
if (dentry->d_inode) {
|
||||||
finish_no_open(od, res);
|
finish_no_open(file, res);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*opened |= FILE_CREATED;
|
*opened |= FILE_CREATED;
|
||||||
err = ceph_lookup_open(dir, dentry, od, flags, mode, opened);
|
err = ceph_lookup_open(dir, dentry, file, flags, mode, opened);
|
||||||
dput(res);
|
dput(res);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
|
|
@ -214,12 +214,11 @@ int ceph_open(struct inode *inode, struct file *file)
|
||||||
* ceph_release gets called). So fear not!
|
* ceph_release gets called). So fear not!
|
||||||
*/
|
*/
|
||||||
int ceph_lookup_open(struct inode *dir, struct dentry *dentry,
|
int ceph_lookup_open(struct inode *dir, struct dentry *dentry,
|
||||||
struct opendata *od, unsigned flags, umode_t mode,
|
struct file *file, unsigned flags, umode_t mode,
|
||||||
int *opened)
|
int *opened)
|
||||||
{
|
{
|
||||||
struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb);
|
struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb);
|
||||||
struct ceph_mds_client *mdsc = fsc->mdsc;
|
struct ceph_mds_client *mdsc = fsc->mdsc;
|
||||||
struct file *file = NULL;
|
|
||||||
struct ceph_mds_request *req;
|
struct ceph_mds_request *req;
|
||||||
struct dentry *ret;
|
struct dentry *ret;
|
||||||
int err;
|
int err;
|
||||||
|
@ -248,9 +247,7 @@ int ceph_lookup_open(struct inode *dir, struct dentry *dentry,
|
||||||
err = ceph_handle_notrace_create(dir, dentry);
|
err = ceph_handle_notrace_create(dir, dentry);
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
goto out;
|
||||||
file = finish_open(od, req->r_dentry, ceph_open, opened);
|
err = finish_open(file, req->r_dentry, ceph_open, opened);
|
||||||
if (IS_ERR(file))
|
|
||||||
err = PTR_ERR(file);
|
|
||||||
out:
|
out:
|
||||||
ret = ceph_finish_lookup(req, dentry, err);
|
ret = ceph_finish_lookup(req, dentry, err);
|
||||||
ceph_mdsc_put_request(req);
|
ceph_mdsc_put_request(req);
|
||||||
|
|
|
@ -807,7 +807,7 @@ extern int ceph_copy_from_page_vector(struct page **pages,
|
||||||
extern struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags);
|
extern struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags);
|
||||||
extern int ceph_open(struct inode *inode, struct file *file);
|
extern int ceph_open(struct inode *inode, struct file *file);
|
||||||
extern int ceph_lookup_open(struct inode *dir, struct dentry *dentry,
|
extern int ceph_lookup_open(struct inode *dir, struct dentry *dentry,
|
||||||
struct opendata *od, unsigned flags,
|
struct file *od, unsigned flags,
|
||||||
umode_t mode, int *opened);
|
umode_t mode, int *opened);
|
||||||
extern int ceph_release(struct inode *inode, struct file *filp);
|
extern int ceph_release(struct inode *inode, struct file *filp);
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,7 @@ extern struct inode *cifs_root_iget(struct super_block *);
|
||||||
extern int cifs_create(struct inode *, struct dentry *, umode_t,
|
extern int cifs_create(struct inode *, struct dentry *, umode_t,
|
||||||
struct nameidata *);
|
struct nameidata *);
|
||||||
extern int cifs_atomic_open(struct inode *, struct dentry *,
|
extern int cifs_atomic_open(struct inode *, struct dentry *,
|
||||||
struct opendata *, unsigned, umode_t,
|
struct file *, unsigned, umode_t,
|
||||||
int *);
|
int *);
|
||||||
extern struct dentry *cifs_lookup(struct inode *, struct dentry *,
|
extern struct dentry *cifs_lookup(struct inode *, struct dentry *,
|
||||||
struct nameidata *);
|
struct nameidata *);
|
||||||
|
|
|
@ -378,7 +378,7 @@ static int cifs_do_create(struct inode *inode, struct dentry *direntry,
|
||||||
|
|
||||||
int
|
int
|
||||||
cifs_atomic_open(struct inode *inode, struct dentry *direntry,
|
cifs_atomic_open(struct inode *inode, struct dentry *direntry,
|
||||||
struct opendata *od, unsigned oflags, umode_t mode,
|
struct file *file, unsigned oflags, umode_t mode,
|
||||||
int *opened)
|
int *opened)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -405,7 +405,7 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
|
||||||
if (IS_ERR(res))
|
if (IS_ERR(res))
|
||||||
return PTR_ERR(res);
|
return PTR_ERR(res);
|
||||||
|
|
||||||
finish_no_open(od, res);
|
finish_no_open(file, res);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,9 +431,8 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry,
|
||||||
if (rc)
|
if (rc)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
filp = finish_open(od, direntry, generic_file_open, opened);
|
rc = finish_open(file, direntry, generic_file_open, opened);
|
||||||
if (IS_ERR(filp)) {
|
if (rc) {
|
||||||
rc = PTR_ERR(filp);
|
|
||||||
CIFSSMBClose(xid, tcon, fileHandle);
|
CIFSSMBClose(xid, tcon, fileHandle);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -370,7 +370,7 @@ static struct dentry *fuse_lookup(struct inode *dir, struct dentry *entry,
|
||||||
* 'mknod' + 'open' requests.
|
* 'mknod' + 'open' requests.
|
||||||
*/
|
*/
|
||||||
static int fuse_create_open(struct inode *dir, struct dentry *entry,
|
static int fuse_create_open(struct inode *dir, struct dentry *entry,
|
||||||
struct opendata *od, unsigned flags,
|
struct file *file, unsigned flags,
|
||||||
umode_t mode, int *opened)
|
umode_t mode, int *opened)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
@ -382,7 +382,6 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry,
|
||||||
struct fuse_open_out outopen;
|
struct fuse_open_out outopen;
|
||||||
struct fuse_entry_out outentry;
|
struct fuse_entry_out outentry;
|
||||||
struct fuse_file *ff;
|
struct fuse_file *ff;
|
||||||
struct file *file;
|
|
||||||
|
|
||||||
forget = fuse_alloc_forget();
|
forget = fuse_alloc_forget();
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
|
@ -450,14 +449,12 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry,
|
||||||
d_instantiate(entry, inode);
|
d_instantiate(entry, inode);
|
||||||
fuse_change_entry_timeout(entry, &outentry);
|
fuse_change_entry_timeout(entry, &outentry);
|
||||||
fuse_invalidate_attr(dir);
|
fuse_invalidate_attr(dir);
|
||||||
file = finish_open(od, entry, generic_file_open, opened);
|
err = finish_open(file, entry, generic_file_open, opened);
|
||||||
if (IS_ERR(file)) {
|
if (err) {
|
||||||
err = PTR_ERR(file);
|
|
||||||
fuse_sync_release(ff, flags);
|
fuse_sync_release(ff, flags);
|
||||||
} else {
|
} else {
|
||||||
file->private_data = fuse_file_get(ff);
|
file->private_data = fuse_file_get(ff);
|
||||||
fuse_finish_open(inode, file);
|
fuse_finish_open(inode, file);
|
||||||
err = 0;
|
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
@ -473,7 +470,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry,
|
||||||
|
|
||||||
static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t);
|
static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t);
|
||||||
static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
|
static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
|
||||||
struct opendata *od, unsigned flags,
|
struct file *file, unsigned flags,
|
||||||
umode_t mode, int *opened)
|
umode_t mode, int *opened)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
@ -498,7 +495,7 @@ static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
|
||||||
if (fc->no_create)
|
if (fc->no_create)
|
||||||
goto mknod;
|
goto mknod;
|
||||||
|
|
||||||
err = fuse_create_open(dir, entry, od, flags, mode, opened);
|
err = fuse_create_open(dir, entry, file, flags, mode, opened);
|
||||||
if (err == -ENOSYS) {
|
if (err == -ENOSYS) {
|
||||||
fc->no_create = 1;
|
fc->no_create = 1;
|
||||||
goto mknod;
|
goto mknod;
|
||||||
|
@ -512,7 +509,7 @@ static int fuse_atomic_open(struct inode *dir, struct dentry *entry,
|
||||||
if (err)
|
if (err)
|
||||||
goto out_dput;
|
goto out_dput;
|
||||||
no_open:
|
no_open:
|
||||||
finish_no_open(od, res);
|
finish_no_open(file, res);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,9 +82,6 @@ extern struct super_block *user_get_super(dev_t);
|
||||||
/*
|
/*
|
||||||
* open.c
|
* open.c
|
||||||
*/
|
*/
|
||||||
struct opendata {
|
|
||||||
struct file *filp;
|
|
||||||
};
|
|
||||||
struct open_flags {
|
struct open_flags {
|
||||||
int open_flag;
|
int open_flag;
|
||||||
umode_t mode;
|
umode_t mode;
|
||||||
|
|
48
fs/namei.c
48
fs/namei.c
|
@ -2194,7 +2194,7 @@ static int may_o_create(struct path *dir, struct dentry *dentry, umode_t mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct file *atomic_open(struct nameidata *nd, struct dentry *dentry,
|
static struct file *atomic_open(struct nameidata *nd, struct dentry *dentry,
|
||||||
struct path *path, struct opendata *od,
|
struct path *path, struct file *file,
|
||||||
const struct open_flags *op,
|
const struct open_flags *op,
|
||||||
bool *want_write, bool need_lookup,
|
bool *want_write, bool need_lookup,
|
||||||
int *opened)
|
int *opened)
|
||||||
|
@ -2269,9 +2269,9 @@ static struct file *atomic_open(struct nameidata *nd, struct dentry *dentry,
|
||||||
if (nd->flags & LOOKUP_DIRECTORY)
|
if (nd->flags & LOOKUP_DIRECTORY)
|
||||||
open_flag |= O_DIRECTORY;
|
open_flag |= O_DIRECTORY;
|
||||||
|
|
||||||
od->filp->f_path.dentry = DENTRY_NOT_SET;
|
file->f_path.dentry = DENTRY_NOT_SET;
|
||||||
od->filp->f_path.mnt = nd->path.mnt;
|
file->f_path.mnt = nd->path.mnt;
|
||||||
error = dir->i_op->atomic_open(dir, dentry, od, open_flag, mode,
|
error = dir->i_op->atomic_open(dir, dentry, file, open_flag, mode,
|
||||||
opened);
|
opened);
|
||||||
if (error < 0) {
|
if (error < 0) {
|
||||||
if (create_error && error == -ENOENT)
|
if (create_error && error == -ENOENT)
|
||||||
|
@ -2287,13 +2287,13 @@ static struct file *atomic_open(struct nameidata *nd, struct dentry *dentry,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error) { /* returned 1, that is */
|
if (error) { /* returned 1, that is */
|
||||||
if (WARN_ON(od->filp->f_path.dentry == DENTRY_NOT_SET)) {
|
if (WARN_ON(file->f_path.dentry == DENTRY_NOT_SET)) {
|
||||||
filp = ERR_PTR(-EIO);
|
filp = ERR_PTR(-EIO);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (od->filp->f_path.dentry) {
|
if (file->f_path.dentry) {
|
||||||
dput(dentry);
|
dput(dentry);
|
||||||
dentry = od->filp->f_path.dentry;
|
dentry = file->f_path.dentry;
|
||||||
}
|
}
|
||||||
goto looked_up;
|
goto looked_up;
|
||||||
}
|
}
|
||||||
|
@ -2302,7 +2302,7 @@ static struct file *atomic_open(struct nameidata *nd, struct dentry *dentry,
|
||||||
* We didn't have the inode before the open, so check open permission
|
* We didn't have the inode before the open, so check open permission
|
||||||
* here.
|
* here.
|
||||||
*/
|
*/
|
||||||
filp = od->filp;
|
filp = file;
|
||||||
error = may_open(&filp->f_path, acc_mode, open_flag);
|
error = may_open(&filp->f_path, acc_mode, open_flag);
|
||||||
if (error) {
|
if (error) {
|
||||||
fput(filp);
|
fput(filp);
|
||||||
|
@ -2350,7 +2350,7 @@ static struct file *atomic_open(struct nameidata *nd, struct dentry *dentry,
|
||||||
* was performed, only lookup.
|
* was performed, only lookup.
|
||||||
*/
|
*/
|
||||||
static struct file *lookup_open(struct nameidata *nd, struct path *path,
|
static struct file *lookup_open(struct nameidata *nd, struct path *path,
|
||||||
struct opendata *od,
|
struct file *file,
|
||||||
const struct open_flags *op,
|
const struct open_flags *op,
|
||||||
bool *want_write, int *opened)
|
bool *want_write, int *opened)
|
||||||
{
|
{
|
||||||
|
@ -2370,7 +2370,7 @@ static struct file *lookup_open(struct nameidata *nd, struct path *path,
|
||||||
goto out_no_open;
|
goto out_no_open;
|
||||||
|
|
||||||
if ((nd->flags & LOOKUP_OPEN) && dir_inode->i_op->atomic_open) {
|
if ((nd->flags & LOOKUP_OPEN) && dir_inode->i_op->atomic_open) {
|
||||||
return atomic_open(nd, dentry, path, od, op, want_write,
|
return atomic_open(nd, dentry, path, file, op, want_write,
|
||||||
need_lookup, opened);
|
need_lookup, opened);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2420,7 +2420,7 @@ static struct file *lookup_open(struct nameidata *nd, struct path *path,
|
||||||
* Handle the last step of open()
|
* Handle the last step of open()
|
||||||
*/
|
*/
|
||||||
static struct file *do_last(struct nameidata *nd, struct path *path,
|
static struct file *do_last(struct nameidata *nd, struct path *path,
|
||||||
struct opendata *od, const struct open_flags *op,
|
struct file *file, const struct open_flags *op,
|
||||||
int *opened, const char *pathname)
|
int *opened, const char *pathname)
|
||||||
{
|
{
|
||||||
struct dentry *dir = nd->path.dentry;
|
struct dentry *dir = nd->path.dentry;
|
||||||
|
@ -2497,7 +2497,7 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
|
||||||
|
|
||||||
retry_lookup:
|
retry_lookup:
|
||||||
mutex_lock(&dir->d_inode->i_mutex);
|
mutex_lock(&dir->d_inode->i_mutex);
|
||||||
filp = lookup_open(nd, path, od, op, &want_write, opened);
|
filp = lookup_open(nd, path, file, op, &want_write, opened);
|
||||||
mutex_unlock(&dir->d_inode->i_mutex);
|
mutex_unlock(&dir->d_inode->i_mutex);
|
||||||
|
|
||||||
if (filp) {
|
if (filp) {
|
||||||
|
@ -2604,13 +2604,15 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
|
||||||
error = may_open(&nd->path, acc_mode, open_flag);
|
error = may_open(&nd->path, acc_mode, open_flag);
|
||||||
if (error)
|
if (error)
|
||||||
goto exit;
|
goto exit;
|
||||||
od->filp->f_path.mnt = nd->path.mnt;
|
file->f_path.mnt = nd->path.mnt;
|
||||||
filp = finish_open(od, nd->path.dentry, NULL, opened);
|
error = finish_open(file, nd->path.dentry, NULL, opened);
|
||||||
if (IS_ERR(filp)) {
|
if (error) {
|
||||||
if (filp == ERR_PTR(-EOPENSTALE))
|
filp = ERR_PTR(error);
|
||||||
|
if (error == -EOPENSTALE)
|
||||||
goto stale_open;
|
goto stale_open;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
filp = file;
|
||||||
opened:
|
opened:
|
||||||
error = open_check_o_direct(filp);
|
error = open_check_o_direct(filp);
|
||||||
if (error)
|
if (error)
|
||||||
|
@ -2663,17 +2665,17 @@ static struct file *path_openat(int dfd, const char *pathname,
|
||||||
struct nameidata *nd, const struct open_flags *op, int flags)
|
struct nameidata *nd, const struct open_flags *op, int flags)
|
||||||
{
|
{
|
||||||
struct file *base = NULL;
|
struct file *base = NULL;
|
||||||
struct opendata od;
|
struct file *file;
|
||||||
struct file *res;
|
struct file *res;
|
||||||
struct path path;
|
struct path path;
|
||||||
int opened = 0;
|
int opened = 0;
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
od.filp = get_empty_filp();
|
file = get_empty_filp();
|
||||||
if (!od.filp)
|
if (!file)
|
||||||
return ERR_PTR(-ENFILE);
|
return ERR_PTR(-ENFILE);
|
||||||
|
|
||||||
od.filp->f_flags = op->open_flag;
|
file->f_flags = op->open_flag;
|
||||||
|
|
||||||
error = path_init(dfd, pathname, flags | LOOKUP_PARENT, nd, &base);
|
error = path_init(dfd, pathname, flags | LOOKUP_PARENT, nd, &base);
|
||||||
if (unlikely(error))
|
if (unlikely(error))
|
||||||
|
@ -2684,7 +2686,7 @@ static struct file *path_openat(int dfd, const char *pathname,
|
||||||
if (unlikely(error))
|
if (unlikely(error))
|
||||||
goto out_filp;
|
goto out_filp;
|
||||||
|
|
||||||
res = do_last(nd, &path, &od, op, &opened, pathname);
|
res = do_last(nd, &path, file, op, &opened, pathname);
|
||||||
while (unlikely(!res)) { /* trailing symlink */
|
while (unlikely(!res)) { /* trailing symlink */
|
||||||
struct path link = path;
|
struct path link = path;
|
||||||
void *cookie;
|
void *cookie;
|
||||||
|
@ -2699,7 +2701,7 @@ static struct file *path_openat(int dfd, const char *pathname,
|
||||||
error = follow_link(&link, nd, &cookie);
|
error = follow_link(&link, nd, &cookie);
|
||||||
if (unlikely(error))
|
if (unlikely(error))
|
||||||
goto out_filp;
|
goto out_filp;
|
||||||
res = do_last(nd, &path, &od, op, &opened, pathname);
|
res = do_last(nd, &path, file, op, &opened, pathname);
|
||||||
put_link(nd, &link, cookie);
|
put_link(nd, &link, cookie);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
|
@ -2708,7 +2710,7 @@ static struct file *path_openat(int dfd, const char *pathname,
|
||||||
if (base)
|
if (base)
|
||||||
fput(base);
|
fput(base);
|
||||||
if (!(opened & FILE_OPENED))
|
if (!(opened & FILE_OPENED))
|
||||||
put_filp(od.filp);
|
put_filp(file);
|
||||||
if (res == ERR_PTR(-EOPENSTALE)) {
|
if (res == ERR_PTR(-EOPENSTALE)) {
|
||||||
if (flags & LOOKUP_RCU)
|
if (flags & LOOKUP_RCU)
|
||||||
res = ERR_PTR(-ECHILD);
|
res = ERR_PTR(-ECHILD);
|
||||||
|
|
20
fs/nfs/dir.c
20
fs/nfs/dir.c
|
@ -112,7 +112,7 @@ const struct inode_operations nfs3_dir_inode_operations = {
|
||||||
#ifdef CONFIG_NFS_V4
|
#ifdef CONFIG_NFS_V4
|
||||||
|
|
||||||
static int nfs_atomic_open(struct inode *, struct dentry *,
|
static int nfs_atomic_open(struct inode *, struct dentry *,
|
||||||
struct opendata *, unsigned, umode_t,
|
struct file *, unsigned, umode_t,
|
||||||
int *);
|
int *);
|
||||||
const struct inode_operations nfs4_dir_inode_operations = {
|
const struct inode_operations nfs4_dir_inode_operations = {
|
||||||
.create = nfs_create,
|
.create = nfs_create,
|
||||||
|
@ -1389,10 +1389,9 @@ static int do_open(struct inode *inode, struct file *filp)
|
||||||
|
|
||||||
static int nfs_finish_open(struct nfs_open_context *ctx,
|
static int nfs_finish_open(struct nfs_open_context *ctx,
|
||||||
struct dentry *dentry,
|
struct dentry *dentry,
|
||||||
struct opendata *od, unsigned open_flags,
|
struct file *file, unsigned open_flags,
|
||||||
int *opened)
|
int *opened)
|
||||||
{
|
{
|
||||||
struct file *filp;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (ctx->dentry != dentry) {
|
if (ctx->dentry != dentry) {
|
||||||
|
@ -1407,13 +1406,10 @@ static int nfs_finish_open(struct nfs_open_context *ctx,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
filp = finish_open(od, dentry, do_open, opened);
|
err = finish_open(file, dentry, do_open, opened);
|
||||||
if (IS_ERR(filp)) {
|
if (err)
|
||||||
err = PTR_ERR(filp);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
nfs_file_set_open_context(file, ctx);
|
||||||
nfs_file_set_open_context(filp, ctx);
|
|
||||||
err = 0;
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
put_nfs_open_context(ctx);
|
put_nfs_open_context(ctx);
|
||||||
|
@ -1421,7 +1417,7 @@ static int nfs_finish_open(struct nfs_open_context *ctx,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
|
static int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
|
||||||
struct opendata *od, unsigned open_flags,
|
struct file *file, unsigned open_flags,
|
||||||
umode_t mode, int *opened)
|
umode_t mode, int *opened)
|
||||||
{
|
{
|
||||||
struct nfs_open_context *ctx;
|
struct nfs_open_context *ctx;
|
||||||
|
@ -1497,7 +1493,7 @@ static int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
|
||||||
nfs_unblock_sillyrename(dentry->d_parent);
|
nfs_unblock_sillyrename(dentry->d_parent);
|
||||||
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
|
nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
|
||||||
|
|
||||||
err = nfs_finish_open(ctx, dentry, od, open_flags, opened);
|
err = nfs_finish_open(ctx, dentry, file, open_flags, opened);
|
||||||
|
|
||||||
dput(res);
|
dput(res);
|
||||||
out:
|
out:
|
||||||
|
@ -1509,7 +1505,7 @@ static int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
|
||||||
if (IS_ERR(res))
|
if (IS_ERR(res))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
finish_no_open(od, res);
|
finish_no_open(file, res);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
20
fs/open.c
20
fs/open.c
|
@ -781,21 +781,23 @@ static struct file *__dentry_open(struct dentry *dentry, struct vfsmount *mnt,
|
||||||
* If the open callback is set to NULL, then the standard f_op->open()
|
* If the open callback is set to NULL, then the standard f_op->open()
|
||||||
* filesystem callback is substituted.
|
* filesystem callback is substituted.
|
||||||
*/
|
*/
|
||||||
struct file *finish_open(struct opendata *od, struct dentry *dentry,
|
int finish_open(struct file *file, struct dentry *dentry,
|
||||||
int (*open)(struct inode *, struct file *),
|
int (*open)(struct inode *, struct file *),
|
||||||
int *opened)
|
int *opened)
|
||||||
{
|
{
|
||||||
struct file *res;
|
struct file *res;
|
||||||
BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */
|
BUG_ON(*opened & FILE_OPENED); /* once it's opened, it's opened */
|
||||||
|
|
||||||
mntget(od->filp->f_path.mnt);
|
mntget(file->f_path.mnt);
|
||||||
dget(dentry);
|
dget(dentry);
|
||||||
|
|
||||||
res = do_dentry_open(dentry, od->filp->f_path.mnt, od->filp, open, current_cred());
|
res = do_dentry_open(dentry, file->f_path.mnt, file, open, current_cred());
|
||||||
if (!IS_ERR(res))
|
if (!IS_ERR(res)) {
|
||||||
*opened |= FILE_OPENED;
|
*opened |= FILE_OPENED;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return res;
|
return PTR_ERR(res);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(finish_open);
|
EXPORT_SYMBOL(finish_open);
|
||||||
|
|
||||||
|
@ -808,9 +810,9 @@ EXPORT_SYMBOL(finish_open);
|
||||||
* This can be used to set the result of a successful lookup in ->atomic_open().
|
* This can be used to set the result of a successful lookup in ->atomic_open().
|
||||||
* The filesystem's atomic_open() method shall return NULL after calling this.
|
* The filesystem's atomic_open() method shall return NULL after calling this.
|
||||||
*/
|
*/
|
||||||
void finish_no_open(struct opendata *od, struct dentry *dentry)
|
void finish_no_open(struct file *file, struct dentry *dentry)
|
||||||
{
|
{
|
||||||
od->filp->f_path.dentry = dentry;
|
file->f_path.dentry = dentry;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(finish_no_open);
|
EXPORT_SYMBOL(finish_no_open);
|
||||||
|
|
||||||
|
|
|
@ -427,7 +427,6 @@ struct kstatfs;
|
||||||
struct vm_area_struct;
|
struct vm_area_struct;
|
||||||
struct vfsmount;
|
struct vfsmount;
|
||||||
struct cred;
|
struct cred;
|
||||||
struct opendata;
|
|
||||||
|
|
||||||
extern void __init inode_init(void);
|
extern void __init inode_init(void);
|
||||||
extern void __init inode_init_early(void);
|
extern void __init inode_init_early(void);
|
||||||
|
@ -1695,7 +1694,7 @@ struct inode_operations {
|
||||||
u64 len);
|
u64 len);
|
||||||
int (*update_time)(struct inode *, struct timespec *, int);
|
int (*update_time)(struct inode *, struct timespec *, int);
|
||||||
int (*atomic_open)(struct inode *, struct dentry *,
|
int (*atomic_open)(struct inode *, struct dentry *,
|
||||||
struct opendata *, unsigned open_flag,
|
struct file *, unsigned open_flag,
|
||||||
umode_t create_mode, int *opened);
|
umode_t create_mode, int *opened);
|
||||||
} ____cacheline_aligned;
|
} ____cacheline_aligned;
|
||||||
|
|
||||||
|
@ -2069,10 +2068,10 @@ enum {
|
||||||
FILE_CREATED = 1,
|
FILE_CREATED = 1,
|
||||||
FILE_OPENED = 2
|
FILE_OPENED = 2
|
||||||
};
|
};
|
||||||
extern struct file *finish_open(struct opendata *od, struct dentry *dentry,
|
extern int finish_open(struct file *file, struct dentry *dentry,
|
||||||
int (*open)(struct inode *, struct file *),
|
int (*open)(struct inode *, struct file *),
|
||||||
int *opened);
|
int *opened);
|
||||||
extern void finish_no_open(struct opendata *od, struct dentry *dentry);
|
extern void finish_no_open(struct file *file, struct dentry *dentry);
|
||||||
|
|
||||||
/* fs/ioctl.c */
|
/* fs/ioctl.c */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue