[linux-cifs-client] Re: lookup intent patch

Shirish Pargaonkar shirishpargaonkar at gmail.com
Mon Mar 30 15:57:32 GMT 2009


On Fri, Mar 27, 2009 at 1:13 PM, Jeff Layton <jlayton at redhat.com> wrote:
> On Fri, 27 Mar 2009 10:15:21 -0500
> Shirish Pargaonkar <shirishpargaonkar at gmail.com> wrote:
>
> Please run this through checkpatch.pl, there is a lot of bad whitespace
> in this patch:
>
>> diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
>> index f9b6f68..011d0ac 100644
>> --- a/fs/cifs/dir.c
>> +++ b/fs/cifs/dir.c
>> @@ -129,12 +129,67 @@ cifs_bp_rename_retry:
>>       return full_path;
>>  }
>>
>> +static void
>> +cifs_fill_fileinfo(struct inode *newinode, __u16 fileHandle,
>> +                     struct cifsTconInfo *tcon, bool write_only)
>> +{
>> +     int oplock = 0;
>> +     struct cifsFileInfo *pCifsFile;
>> +     struct cifsInodeInfo *pCifsInode;
>> +
>> +     cERROR(1, ("cifs_fill_fileinfo enter\n"));
>> +
>> +     pCifsFile = kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
>> +
>> +     if (pCifsFile == NULL)
>> +             return;
>> +
>> +     if (oplockEnabled)
>> +             oplock = REQ_OPLOCK;
>> +
>> +     pCifsFile->netfid = fileHandle;
>> +     pCifsFile->pid = current->tgid;
>> +     pCifsFile->pInode = newinode;
>> +     pCifsFile->invalidHandle = false;
>> +     pCifsFile->closePend     = false;
>> +     init_MUTEX(&pCifsFile->fh_sem);
>            ^^^^
> Can you convert this to a mutex while you're at it? Might not hurt to make
> that a separate patch though.
>
>> +     mutex_init(&pCifsFile->lock_mutex);
>> +     INIT_LIST_HEAD(&pCifsFile->llist);
>> +     atomic_set(&pCifsFile->wrtPending, 0);
>> +
>> +     /* set the following in open now
>> +                     pCifsFile->pfile = file; */
>> +     write_lock(&GlobalSMBSeslock);
>> +     list_add(&pCifsFile->tlist, &tcon->openFileList);
>> +     pCifsInode = CIFS_I(newinode);
>> +     if (pCifsInode) {
>> +             /* if readable file instance put first in list*/
>> +             if (write_only) {
>> +                     list_add_tail(&pCifsFile->flist,
>> +                                   &pCifsInode->openFileList);
>> +             } else {
>> +                     list_add(&pCifsFile->flist,
>> +                              &pCifsInode->openFileList);
>> +             }
>> +             if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
>> +                     pCifsInode->clientCanCacheAll = true;
>> +                     pCifsInode->clientCanCacheRead = true;
>> +                     cFYI(1, ("Exclusive Oplock inode %p",
>> +                             newinode));
>> +             } else if ((oplock & 0xF) == OPLOCK_READ)
>> +                     pCifsInode->clientCanCacheRead = true;
>> +     }
>> +     write_unlock(&GlobalSMBSeslock);
>> +     cERROR(1, ("cifs_fill_fileinfo exit\n"));
>> +}
>> +
>>  int cifs_posix_open(char *full_path, struct inode **pinode,
>>                   struct super_block *sb, int mode, int oflags,
>>                   int *poplock, __u16 *pnetfid, int xid)
>>  {
>>       int rc;
>>       __u32 oplock;
>> +     bool write_only = false;
>>       FILE_UNIX_BASIC_INFO *presp_data;
>>       __u32 posix_flags = 0;
>>       struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
>> @@ -172,6 +227,8 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
>>       if (oflags & O_DIRECT)
>>               posix_flags |= SMB_O_DIRECT;
>>
>> +        if (!(oflags & FMODE_READ))
>> +                write_only = true;
>>
>>       rc = CIFSPOSIXCreate(xid, cifs_sb->tcon, posix_flags, mode,
>>                       pnetfid, presp_data, &oplock, full_path,
>> @@ -198,6 +255,8 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
>>
>>       posix_fill_in_inode(*pinode, presp_data, 1);
>>
>> +     cifs_fill_fileinfo(*pinode, *pnetfid, cifs_sb->tcon, write_only);
>> +
>>  posix_open_ret:
>>       kfree(presp_data);
>>       return rc;
>> @@ -239,7 +298,6 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
>>       char *full_path = NULL;
>>       FILE_ALL_INFO *buf = NULL;
>>       struct inode *newinode = NULL;
>> -     struct cifsInodeInfo *pCifsInode;
>>       int disposition = FILE_OVERWRITE_IF;
>>       bool write_only = false;
>>
>> @@ -410,44 +468,8 @@ cifs_create_set_dentry:
>>               /* mknod case - do not leave file open */
>>               CIFSSMBClose(xid, tcon, fileHandle);
>>       } else if (newinode) {
>> -             struct cifsFileInfo *pCifsFile =
>> -                     kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL);
>> -
>> -             if (pCifsFile == NULL)
>> -                     goto cifs_create_out;
>> -             pCifsFile->netfid = fileHandle;
>> -             pCifsFile->pid = current->tgid;
>> -             pCifsFile->pInode = newinode;
>> -             pCifsFile->invalidHandle = false;
>> -             pCifsFile->closePend     = false;
>> -             init_MUTEX(&pCifsFile->fh_sem);
>> -             mutex_init(&pCifsFile->lock_mutex);
>> -             INIT_LIST_HEAD(&pCifsFile->llist);
>> -             atomic_set(&pCifsFile->wrtPending, 0);
>> -
>> -             /* set the following in open now
>> -                             pCifsFile->pfile = file; */
>> -             write_lock(&GlobalSMBSeslock);
>> -             list_add(&pCifsFile->tlist, &tcon->openFileList);
>> -             pCifsInode = CIFS_I(newinode);
>> -             if (pCifsInode) {
>> -                     /* if readable file instance put first in list*/
>> -                     if (write_only) {
>> -                             list_add_tail(&pCifsFile->flist,
>> -                                           &pCifsInode->openFileList);
>> -                     } else {
>> -                             list_add(&pCifsFile->flist,
>> -                                      &pCifsInode->openFileList);
>> -                     }
>> -                     if ((oplock & 0xF) == OPLOCK_EXCLUSIVE) {
>> -                             pCifsInode->clientCanCacheAll = true;
>> -                             pCifsInode->clientCanCacheRead = true;
>> -                             cFYI(1, ("Exclusive Oplock inode %p",
>> -                                     newinode));
>> -                     } else if ((oplock & 0xF) == OPLOCK_READ)
>> -                             pCifsInode->clientCanCacheRead = true;
>> -             }
>> -             write_unlock(&GlobalSMBSeslock);
>> +                     cifs_fill_fileinfo(newinode, fileHandle,
>> +                                     cifs_sb->tcon, write_only);
>>       }
>>  cifs_create_out:
>>       kfree(buf);
>> @@ -580,13 +602,16 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
>>       return rc;
>>  }
>>
>> -
>>  struct dentry *
>>  cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
>>           struct nameidata *nd)
>>  {
>>       int xid;
>>       int rc = 0; /* to get around spurious gcc warning, set to zero here */
>> +     int oplock = 0;
>> +     int mode;
>> +     __u16 fileHandle = 0;
>> +     bool posix_open = false;
>>       struct cifs_sb_info *cifs_sb;
>>       struct cifsTconInfo *pTcon;
>>       struct inode *newInode = NULL;
>> @@ -632,12 +657,26 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
>>       }
>>       cFYI(1, ("Full path: %s inode = 0x%p", full_path, direntry->d_inode));
>>
>> -     if (pTcon->unix_ext)
>> -             rc = cifs_get_inode_info_unix(&newInode, full_path,
>> -                                           parent_dir_inode->i_sb, xid);
>> -     else
>> +     if (pTcon->unix_ext) {
>> +             if (!(nd->flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY)) &&
>> +                             (nd->flags & LOOKUP_OPEN)) {
>> +                     if (!((nd->intent.open.flags & O_CREAT ) &&
>> +                                     (nd->intent.open.flags & O_EXCL))) {
>> +                             mode = nd->intent.open.create_mode &
>> +                                             ~current->fs->umask;
>> +                             rc = cifs_posix_open(full_path, &newInode,
>> +                                     parent_dir_inode->i_sb, mode,
>> +                                     nd->intent.open.flags, &oplock,
>> +                                     &fileHandle, xid);
>> +                             posix_open = true;
>> +                     }
>> +             }
>> +             if (!posix_open || ((rc == -EINVAL) || (rc == -EOPNOTSUPP)))
>> +                     rc = cifs_get_inode_info_unix(&newInode, full_path,
>> +                                             parent_dir_inode->i_sb, xid);
>> +     } else
>>               rc = cifs_get_inode_info(&newInode, full_path, NULL,
>> -                                      parent_dir_inode->i_sb, xid, NULL);
>> +                             parent_dir_inode->i_sb, xid, NULL);
>>
>
> Ok, so you're opening the file on lookup now. Aren't you supposed to use
> lookup_instantiate_filp() to pass an instantiated file pointer back to the
> caller? If you don't do this, then I think you're susceptible to leaking
> this open file if an error occurs between the lookup and the open.
>
> nfs4 does something very similar to what you're trying to do here. You
> might want to look carefully at it as an example. nfs4_atomic_open()
> is a good place to start.
>
>>       if ((rc == 0) && (newInode != NULL)) {
>>               if (pTcon->nocase)
>> diff --git a/fs/cifs/file.c b/fs/cifs/file.c
>> index 81747ac..4a7c886 100644
>> --- a/fs/cifs/file.c
>> +++ b/fs/cifs/file.c
>> @@ -284,35 +284,34 @@ int cifs_open(struct inode *inode, struct file *file)
>>       cifs_sb = CIFS_SB(inode->i_sb);
>>       tcon = cifs_sb->tcon;
>>
>> -     if (file->f_flags & O_CREAT) {
>> -             /* search inode for this file and fill in file->private_data */
>> -             pCifsInode = CIFS_I(file->f_path.dentry->d_inode);
>> -             read_lock(&GlobalSMBSeslock);
>> -             list_for_each(tmp, &pCifsInode->openFileList) {
>> -                     pCifsFile = list_entry(tmp, struct cifsFileInfo,
>> -                                            flist);
>> -                     if ((pCifsFile->pfile == NULL) &&
>> -                         (pCifsFile->pid == current->tgid)) {
>> -                             /* mode set in cifs_create */
>> -
>> -                             /* needed for writepage */
>> -                             pCifsFile->pfile = file;
>> -
>> -                             file->private_data = pCifsFile;
>> -                             break;
>> -                     }
>> -             }
>> -             read_unlock(&GlobalSMBSeslock);
>> -             if (file->private_data != NULL) {
>> -                     rc = 0;
>> -                     FreeXid(xid);
>> -                     return rc;
>> -             } else {
>> -                     if (file->f_flags & O_EXCL)
>> -                             cERROR(1, ("could not find file instance for "
>> -                                        "new file %p", file));
>> +     /* search inode for this file and fill in file->private_data */
>> +     pCifsInode = CIFS_I(file->f_path.dentry->d_inode);
>> +     read_lock(&GlobalSMBSeslock);
>> +     list_for_each(tmp, &pCifsInode->openFileList) {
>> +             pCifsFile = list_entry(tmp, struct cifsFileInfo,
>> +                                    flist);
>> +             if ((pCifsFile->pfile == NULL) &&
>> +                 (pCifsFile->pid == current->tgid)) {
>> +                     /* mode set in cifs_create */
>> +
>> +                     /* needed for writepage */
>> +                     pCifsFile->pfile = file;
>> +
>> +                     file->private_data = pCifsFile;
>> +                     break;
>>               }
>>       }
>> +     read_unlock(&GlobalSMBSeslock);
>> +
>> +     if (file->private_data != NULL) {
>> +             rc = 0;
>> +             FreeXid(xid);
>> +             return rc;
>> +     } else {
>> +             if ((file->f_flags & O_CREAT) && (file->f_flags & O_EXCL))
>> +                     cERROR(1, ("could not find file instance for "
>> +                                "new file %p", file));
>> +     }
>>
>>       full_path = build_path_from_dentry(file->f_path.dentry);
>>       if (full_path == NULL) {
>
>
> --
> Jeff Layton <jlayton at redhat.com>
>

Jeff,

Thanks.  Looking into it. I am trying to figure out the need/necessity
for cifs_lookup to call lookup_instanitate_flip.
lookup_instantiate_filp does call dentry_open and if cifs_lookup does
not call lookup_instantiate_flip,
nameidata_to_filp will call dentry_open.
So I am not sure what we loose if dentry_open does not get called
between lookup_hash and nameidata_to_flip
because of an error between those two calls, specifically how will the
cause of open file getting closed on the
server will be served if there was an in-betwen error by calling
lookup_instantiate_filp.

Regards,

Shirish


More information about the linux-cifs-client mailing list