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>
int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len);
void (*update_time)(struct inode *, struct timespec *, int);
int (*atomic_open)(struct inode *, struct dentry *,
- struct opendata *, unsigned open_flag,
+ struct file *, unsigned open_flag,
umode_t create_mode, int *opened);
locking rules:
int (*removexattr) (struct dentry *, const char *);
void (*update_time)(struct inode *, struct timespec *, int);
int (*atomic_open)(struct inode *, struct dentry *,
- struct opendata *, unsigned open_flag,
+ struct file *, unsigned open_flag,
umode_t create_mode, int *opened);
};
static int
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 err;
u32 perm;
- struct file *filp;
struct v9fs_inode *v9inode;
struct v9fs_session_info *v9ses;
struct p9_fid *fid, *inode_fid;
/* Only creates */
if (!(flags & O_CREAT) || dentry->d_inode) {
- finish_no_open(od, res);
+ finish_no_open(file, res);
return 1;
}
v9inode->writeback_fid = (void *) inode_fid;
}
mutex_unlock(&v9inode->v_mutex);
- filp = finish_open(od, dentry, generic_file_open, opened);
- if (IS_ERR(filp)) {
- err = PTR_ERR(filp);
+ err = finish_open(file, dentry, generic_file_open, opened);
+ if (err)
goto error;
- }
- filp->private_data = fid;
+ file->private_data = fid;
#ifdef CONFIG_9P_FSCACHE
if (v9ses->cache)
- v9fs_cache_inode_set_cookie(dentry->d_inode, filp);
+ v9fs_cache_inode_set_cookie(dentry->d_inode, file);
#endif
*opened |= FILE_CREATED;
static int
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 err = 0;
gid_t gid;
umode_t mode;
char *name = NULL;
- struct file *filp;
struct p9_qid qid;
struct inode *inode;
struct p9_fid *fid = NULL;
/* Only creates */
if (!(flags & O_CREAT) || dentry->d_inode) {
- finish_no_open(od, res);
+ finish_no_open(file, res);
return 1;
}
}
mutex_unlock(&v9inode->v_mutex);
/* Since we are opening a file, assign the open fid to the file */
- filp = finish_open(od, dentry, generic_file_open, opened);
- if (IS_ERR(filp)) {
- err = PTR_ERR(filp);
+ err = finish_open(file, dentry, generic_file_open, opened);
+ if (err)
goto err_clunk_old_fid;
- }
- filp->private_data = ofid;
+ file->private_data = ofid;
#ifdef CONFIG_9P_FSCACHE
if (v9ses->cache)
- v9fs_cache_inode_set_cookie(inode, filp);
+ v9fs_cache_inode_set_cookie(inode, file);
#endif
*opened |= FILE_CREATED;
out:
}
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 err;
if (err < 0)
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)) {
/* We don't deal with positive dentries here */
if (dentry->d_inode) {
- finish_no_open(od, res);
+ finish_no_open(file, res);
return 1;
}
*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);
return err;
* ceph_release gets called). So fear not!
*/
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)
{
struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb);
struct ceph_mds_client *mdsc = fsc->mdsc;
- struct file *file = NULL;
struct ceph_mds_request *req;
struct dentry *ret;
int err;
err = ceph_handle_notrace_create(dir, dentry);
if (err)
goto out;
- file = finish_open(od, req->r_dentry, ceph_open, opened);
- if (IS_ERR(file))
- err = PTR_ERR(file);
+ err = finish_open(file, req->r_dentry, ceph_open, opened);
out:
ret = ceph_finish_lookup(req, dentry, err);
ceph_mdsc_put_request(req);
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_lookup_open(struct inode *dir, struct dentry *dentry,
- struct opendata *od, unsigned flags,
+ struct file *od, unsigned flags,
umode_t mode, int *opened);
extern int ceph_release(struct inode *inode, struct file *filp);
extern int cifs_create(struct inode *, struct dentry *, umode_t,
struct nameidata *);
extern int cifs_atomic_open(struct inode *, struct dentry *,
- struct opendata *, unsigned, umode_t,
+ struct file *, unsigned, umode_t,
int *);
extern struct dentry *cifs_lookup(struct inode *, struct dentry *,
struct nameidata *);
int
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 rc;
if (IS_ERR(res))
return PTR_ERR(res);
- finish_no_open(od, res);
+ finish_no_open(file, res);
return 1;
}
if (rc)
goto out;
- filp = finish_open(od, direntry, generic_file_open, opened);
- if (IS_ERR(filp)) {
- rc = PTR_ERR(filp);
+ rc = finish_open(file, direntry, generic_file_open, opened);
+ if (rc) {
CIFSSMBClose(xid, tcon, fileHandle);
goto out;
}
* 'mknod' + 'open' requests.
*/
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)
{
int err;
struct fuse_open_out outopen;
struct fuse_entry_out outentry;
struct fuse_file *ff;
- struct file *file;
forget = fuse_alloc_forget();
err = -ENOMEM;
d_instantiate(entry, inode);
fuse_change_entry_timeout(entry, &outentry);
fuse_invalidate_attr(dir);
- file = finish_open(od, entry, generic_file_open, opened);
- if (IS_ERR(file)) {
- err = PTR_ERR(file);
+ err = finish_open(file, entry, generic_file_open, opened);
+ if (err) {
fuse_sync_release(ff, flags);
} else {
file->private_data = fuse_file_get(ff);
fuse_finish_open(inode, file);
- err = 0;
}
return err;
static int fuse_mknod(struct inode *, struct dentry *, umode_t, dev_t);
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)
{
int err;
if (fc->no_create)
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) {
fc->no_create = 1;
goto mknod;
if (err)
goto out_dput;
no_open:
- finish_no_open(od, res);
+ finish_no_open(file, res);
return 1;
}
/*
* open.c
*/
-struct opendata {
- struct file *filp;
-};
struct open_flags {
int open_flag;
umode_t mode;
}
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,
bool *want_write, bool need_lookup,
int *opened)
if (nd->flags & LOOKUP_DIRECTORY)
open_flag |= O_DIRECTORY;
- od->filp->f_path.dentry = DENTRY_NOT_SET;
- od->filp->f_path.mnt = nd->path.mnt;
- error = dir->i_op->atomic_open(dir, dentry, od, open_flag, mode,
+ file->f_path.dentry = DENTRY_NOT_SET;
+ file->f_path.mnt = nd->path.mnt;
+ error = dir->i_op->atomic_open(dir, dentry, file, open_flag, mode,
opened);
if (error < 0) {
if (create_error && error == -ENOENT)
}
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);
goto out;
}
- if (od->filp->f_path.dentry) {
+ if (file->f_path.dentry) {
dput(dentry);
- dentry = od->filp->f_path.dentry;
+ dentry = file->f_path.dentry;
}
goto looked_up;
}
* We didn't have the inode before the open, so check open permission
* here.
*/
- filp = od->filp;
+ filp = file;
error = may_open(&filp->f_path, acc_mode, open_flag);
if (error) {
fput(filp);
* was performed, only lookup.
*/
static struct file *lookup_open(struct nameidata *nd, struct path *path,
- struct opendata *od,
+ struct file *file,
const struct open_flags *op,
bool *want_write, int *opened)
{
goto out_no_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);
}
* Handle the last step of open()
*/
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)
{
struct dentry *dir = nd->path.dentry;
retry_lookup:
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);
if (filp) {
error = may_open(&nd->path, acc_mode, open_flag);
if (error)
goto exit;
- od->filp->f_path.mnt = nd->path.mnt;
- filp = finish_open(od, nd->path.dentry, NULL, opened);
- if (IS_ERR(filp)) {
- if (filp == ERR_PTR(-EOPENSTALE))
+ file->f_path.mnt = nd->path.mnt;
+ error = finish_open(file, nd->path.dentry, NULL, opened);
+ if (error) {
+ filp = ERR_PTR(error);
+ if (error == -EOPENSTALE)
goto stale_open;
goto out;
}
+ filp = file;
opened:
error = open_check_o_direct(filp);
if (error)
struct nameidata *nd, const struct open_flags *op, int flags)
{
struct file *base = NULL;
- struct opendata od;
+ struct file *file;
struct file *res;
struct path path;
int opened = 0;
int error;
- od.filp = get_empty_filp();
- if (!od.filp)
+ file = get_empty_filp();
+ if (!file)
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);
if (unlikely(error))
if (unlikely(error))
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 */
struct path link = path;
void *cookie;
error = follow_link(&link, nd, &cookie);
if (unlikely(error))
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);
}
out:
if (base)
fput(base);
if (!(opened & FILE_OPENED))
- put_filp(od.filp);
+ put_filp(file);
if (res == ERR_PTR(-EOPENSTALE)) {
if (flags & LOOKUP_RCU)
res = ERR_PTR(-ECHILD);
#ifdef CONFIG_NFS_V4
static int nfs_atomic_open(struct inode *, struct dentry *,
- struct opendata *, unsigned, umode_t,
+ struct file *, unsigned, umode_t,
int *);
const struct inode_operations nfs4_dir_inode_operations = {
.create = nfs_create,
static int nfs_finish_open(struct nfs_open_context *ctx,
struct dentry *dentry,
- struct opendata *od, unsigned open_flags,
+ struct file *file, unsigned open_flags,
int *opened)
{
- struct file *filp;
int err;
if (ctx->dentry != dentry) {
goto out;
}
- filp = finish_open(od, dentry, do_open, opened);
- if (IS_ERR(filp)) {
- err = PTR_ERR(filp);
+ err = finish_open(file, dentry, do_open, opened);
+ if (err)
goto out;
- }
- nfs_file_set_open_context(filp, ctx);
- err = 0;
+ nfs_file_set_open_context(file, ctx);
out:
put_nfs_open_context(ctx);
}
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)
{
struct nfs_open_context *ctx;
nfs_unblock_sillyrename(dentry->d_parent);
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);
out:
if (IS_ERR(res))
goto out;
- finish_no_open(od, res);
+ finish_no_open(file, res);
return 1;
}
* If the open callback is set to NULL, then the standard f_op->open()
* filesystem callback is substituted.
*/
-struct file *finish_open(struct opendata *od, struct dentry *dentry,
- int (*open)(struct inode *, struct file *),
- int *opened)
+int finish_open(struct file *file, struct dentry *dentry,
+ int (*open)(struct inode *, struct file *),
+ int *opened)
{
struct file *res;
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);
- res = do_dentry_open(dentry, od->filp->f_path.mnt, od->filp, open, current_cred());
- if (!IS_ERR(res))
+ res = do_dentry_open(dentry, file->f_path.mnt, file, open, current_cred());
+ if (!IS_ERR(res)) {
*opened |= FILE_OPENED;
+ return 0;
+ }
- return res;
+ return PTR_ERR(res);
}
EXPORT_SYMBOL(finish_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.
*/
-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);
struct vm_area_struct;
struct vfsmount;
struct cred;
-struct opendata;
extern void __init inode_init(void);
extern void __init inode_init_early(void);
u64 len);
int (*update_time)(struct inode *, struct timespec *, int);
int (*atomic_open)(struct inode *, struct dentry *,
- struct opendata *, unsigned open_flag,
+ struct file *, unsigned open_flag,
umode_t create_mode, int *opened);
} ____cacheline_aligned;
FILE_CREATED = 1,
FILE_OPENED = 2
};
-extern struct file *finish_open(struct opendata *od, struct dentry *dentry,
- int (*open)(struct inode *, struct file *),
- int *opened);
-extern void finish_no_open(struct opendata *od, struct dentry *dentry);
+extern int finish_open(struct file *file, struct dentry *dentry,
+ int (*open)(struct inode *, struct file *),
+ int *opened);
+extern void finish_no_open(struct file *file, struct dentry *dentry);
/* fs/ioctl.c */