[linux-cifs-client] [PATCH 3/4] cifs: move cifs_new_fileinfo call out of cifs_posix_open
Jeff Layton
jlayton at redhat.com
Mon May 24 04:48:40 MDT 2010
On Mon, 24 May 2010 12:20:28 +0530
Suresh Jayaraman <sjayaraman at suse.de> wrote:
> On 05/21/2010 11:55 PM, Jeff Layton wrote:
> > Having cifs_posix_open call cifs_new_fileinfo is problematic and
> > inconsistent with how "regular" opens work. It's also buggy as
> > cifs_reopen_file calls this function on a reconnect, which creates a new
> > fileinfo struct that just gets leaked.
> >
> > Push it out into the callers. This also allows us to get rid of the
> > "mnt" arg to cifs_posix_open.
> >
> > Signed-off-by: Jeff Layton <jlayton at redhat.com>
> > ---
> > fs/cifs/cifsproto.h | 1 -
> > fs/cifs/dir.c | 38 +++++++++++++++-----------------------
> > fs/cifs/file.c | 17 ++++++++++++-----
> > 3 files changed, 27 insertions(+), 29 deletions(-)
> >
> > diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
> > index fb1657e..fb6318b 100644
> > --- a/fs/cifs/cifsproto.h
> > +++ b/fs/cifs/cifsproto.h
> > @@ -106,7 +106,6 @@ extern struct cifsFileInfo *cifs_new_fileinfo(struct inode *newinode,
> > __u16 fileHandle, struct file *file,
> > struct vfsmount *mnt, unsigned int oflags);
> > extern int cifs_posix_open(char *full_path, struct inode **pinode,
> > - struct vfsmount *mnt,
> > struct super_block *sb,
> > int mode, int oflags,
> > __u32 *poplock, __u16 *pnetfid, int xid);
> > diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
> > index e11ee2e..fc3129b 100644
> > --- a/fs/cifs/dir.c
> > +++ b/fs/cifs/dir.c
> > @@ -188,8 +188,7 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle,
> > }
> >
> > int cifs_posix_open(char *full_path, struct inode **pinode,
> > - struct vfsmount *mnt, struct super_block *sb,
> > - int mode, int oflags,
> > + struct super_block *sb, int mode, int oflags,
> > __u32 *poplock, __u16 *pnetfid, int xid)
> > {
> > int rc;
> > @@ -258,21 +257,6 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
> > cifs_fattr_to_inode(*pinode, &fattr);
> > }
> >
> > - /*
> > - * cifs_fill_filedata() takes care of setting cifsFileInfo pointer to
> > - * file->private_data.
> > - */
> > - if (mnt) {
> > - struct cifsFileInfo *pfile_info;
> > -
> > - pfile_info = cifs_new_fileinfo(*pinode, *pnetfid, NULL, mnt,
> > - oflags);
> > - if (pfile_info == NULL)
> > - rc = -ENOMEM;
> > - } else {
> > - CIFSSMBClose(xid, cifs_sb->tcon, *pnetfid);
> > - }
> > -
> > posix_open_ret:
> > kfree(presp_data);
> > return rc;
> > @@ -300,7 +284,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
> > int create_options = CREATE_NOT_DIR;
> > __u32 oplock = 0;
> > int oflags;
> > - bool posix_create = false;
> > /*
> > * BB below access is probably too much for mknod to request
> > * but we have to do query and setpathinfo so requesting
> > @@ -341,7 +324,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
> > (CIFS_UNIX_POSIX_PATH_OPS_CAP &
> > le64_to_cpu(tcon->fsUnixInfo.Capability))) {
> > rc = cifs_posix_open(full_path, &newinode,
> > - nd ? nd->path.mnt : NULL,
> > inode->i_sb, mode, oflags, &oplock, &fileHandle, xid);
> > /* EIO could indicate that (posix open) operation is not
> > supported, despite what server claimed in capability
> > @@ -349,7 +331,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
> > handled in posix open */
> >
> > if (rc == 0) {
> > - posix_create = true;
> > if (newinode == NULL) /* query inode info */
> > goto cifs_create_get_file_info;
> > else /* success, no need to query */
> > @@ -480,7 +461,7 @@ cifs_create_set_dentry:
> > else
> > cFYI(1, "Create worked, get_inode_info failed rc = %d", rc);
> >
> > - if (!posix_create && newinode) {
> > + if (newinode) {
> > struct cifsFileInfo *pfile_info;
> > /*
> > * cifs_fill_filedata() takes care of setting cifsFileInfo
> > @@ -637,6 +618,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
> > bool posix_open = false;
> > struct cifs_sb_info *cifs_sb;
> > struct cifsTconInfo *pTcon;
> > + struct cifsFileInfo *cfile;
> > struct inode *newInode = NULL;
> > char *full_path = NULL;
> > struct file *filp;
> > @@ -705,7 +687,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
> > if (nd && !(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) &&
> > (nd->flags & LOOKUP_OPEN) && !pTcon->broken_posix_open &&
> > (nd->intent.open.flags & O_CREAT)) {
> > - rc = cifs_posix_open(full_path, &newInode, nd->path.mnt,
> > + rc = cifs_posix_open(full_path, &newInode,
> > parent_dir_inode->i_sb,
> > nd->intent.open.create_mode,
> > nd->intent.open.flags, &oplock,
> > @@ -735,8 +717,17 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
> > else
> > direntry->d_op = &cifs_dentry_ops;
> > d_add(direntry, newInode);
> > - if (posix_open)
> > + if (posix_open) {
> > + cfile = cifs_new_fileinfo(newInode, fileHandle, NULL,
> > + nd->path.mnt,
> > + nd->intent.open.flags);
> > + if (cfile == NULL) {
> > + CIFSSMBClose(xid, pTcon, fileHandle);
> > + res = ERR_PTR(ENOMEM);
>
> Should be ERR_PTR(-ENOMEM)?
>
> If you are planning to drop patch [1/4], res goes undeclared.
>
Good catch, will fix in next set.
> > + goto lookup_out;
> > + }
> > filp = lookup_instantiate_filp(nd, direntry, NULL);
> > + }
> > /* since paths are not looked up by component - the parent
> > directories are presumed to be good here */
> > renew_parental_timestamps(direntry);
> > @@ -761,6 +752,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
> > res = ERR_PTR(rc);
> > }
> >
> > +lookup_out:
> > kfree(full_path);
> > FreeXid(xid);
> > return res;
> > diff --git a/fs/cifs/file.c b/fs/cifs/file.c
> > index a83541e..001e916 100644
> > --- a/fs/cifs/file.c
> > +++ b/fs/cifs/file.c
> > @@ -299,8 +299,7 @@ int cifs_open(struct inode *inode, struct file *file)
> > int oflags = (int) cifs_posix_convert_flags(file->f_flags);
> > oflags |= SMB_O_CREAT;
> > /* can not refresh inode info since size could be stale */
> > - rc = cifs_posix_open(full_path, &inode, file->f_path.mnt,
> > - inode->i_sb,
> > + rc = cifs_posix_open(full_path, &inode, inode->i_sb,
> > cifs_sb->mnt_file_mode /* ignored */,
> > oflags, &oplock, &netfid, xid);
> > if (rc == 0) {
> > @@ -308,7 +307,16 @@ int cifs_open(struct inode *inode, struct file *file)
> > /* no need for special case handling of setting mode
> > on read only files needed here */
> >
> > - pCifsFile = cifs_fill_filedata(file);
> > + pCifsFile = cifs_new_fileinfo(inode, netfid, file,
> > + file->f_path.mnt,
> > + oflags);
> > + if (pCifsFile == NULL) {
> > + CIFSSMBClose(xid, tcon, netfid);
> > + rc = -ENOMEM;
> > + goto out;
> > + }
> > + file->private_data = pCifsFile;
> > +
> > cifs_posix_open_inode_helper(inode, file, pCifsInode,
> > oplock, netfid);
> > goto out;
> > @@ -513,8 +521,7 @@ reopen_error_exit:
> > le64_to_cpu(tcon->fsUnixInfo.Capability))) {
> > int oflags = (int) cifs_posix_convert_flags(file->f_flags);
> > /* can not refresh inode info since size could be stale */
> > - rc = cifs_posix_open(full_path, NULL, file->f_path.mnt,
> > - inode->i_sb,
> > + rc = cifs_posix_open(full_path, NULL, inode->i_sb,
> > cifs_sb->mnt_file_mode /* ignored */,
> > oflags, &oplock, &netfid, xid);
> > if (rc == 0) {
>
>
--
Jeff Layton <jlayton at redhat.com>
More information about the linux-cifs-client
mailing list