Re: [PATCH] cifs: cleanups for cifs_mkdir_qinfo

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



2012/9/5 Jeff Layton <jlayton@xxxxxxxxxx>:
> Rename inode pointers for better clarity. Move the d_instantiate call to
> the end of the function to prevent other tasks from seeing it before
> we've finished constructing it. Since we should have exclusive access to
> the inode at this point, remove the spinlock around i_nlink update.
>
> Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx>
> ---
>  fs/cifs/inode.c | 51 ++++++++++++++++++++++++---------------------------
>  1 file changed, 24 insertions(+), 27 deletions(-)
>
> diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
> index da4dd71..fd6551b 100644
> --- a/fs/cifs/inode.c
> +++ b/fs/cifs/inode.c
> @@ -1176,34 +1176,33 @@ unlink_out:
>  }
>
>  static int
> -cifs_mkdir_qinfo(struct inode *inode, struct dentry *dentry, umode_t mode,
> +cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode,
>                  const char *full_path, struct cifs_sb_info *cifs_sb,
>                  struct cifs_tcon *tcon, const unsigned int xid)
>  {
>         int rc = 0;
> -       struct inode *newinode = NULL;
> +       struct inode *inode = NULL;
>
>         if (tcon->unix_ext)
> -               rc = cifs_get_inode_info_unix(&newinode, full_path, inode->i_sb,
> +               rc = cifs_get_inode_info_unix(&inode, full_path, parent->i_sb,
>                                               xid);
>         else
> -               rc = cifs_get_inode_info(&newinode, full_path, NULL,
> -                                        inode->i_sb, xid, NULL);
> +               rc = cifs_get_inode_info(&inode, full_path, NULL, parent->i_sb,
> +                                        xid, NULL);
> +
>         if (rc)
>                 return rc;
>
> -       d_instantiate(dentry, newinode);
>         /*
>          * setting nlink not necessary except in cases where we failed to get it
> -        * from the server or was set bogus
> +        * from the server or was set bogus. Also, since this is a brand new
> +        * inode, no need to grab the i_lock before setting the i_nlink.
>          */
> -       spin_lock(&dentry->d_inode->i_lock);
> -       if ((dentry->d_inode) && (dentry->d_inode->i_nlink < 2))
> -               set_nlink(dentry->d_inode, 2);
> -       spin_unlock(&dentry->d_inode->i_lock);
> +       if (inode->i_nlink < 2)
> +               set_nlink(inode, 2);
>         mode &= ~current_umask();
>         /* must turn on setgid bit if parent dir has it */
> -       if (inode->i_mode & S_ISGID)
> +       if (parent->i_mode & S_ISGID)
>                 mode |= S_ISGID;
>
>         if (tcon->unix_ext) {
> @@ -1216,8 +1215,8 @@ cifs_mkdir_qinfo(struct inode *inode, struct dentry *dentry, umode_t mode,
>                 };
>                 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
>                         args.uid = (__u64)current_fsuid();
> -                       if (inode->i_mode & S_ISGID)
> -                               args.gid = (__u64)inode->i_gid;
> +                       if (parent->i_mode & S_ISGID)
> +                               args.gid = (__u64)parent->i_gid;
>                         else
>                                 args.gid = (__u64)current_fsgid();
>                 } else {
> @@ -1232,22 +1231,20 @@ cifs_mkdir_qinfo(struct inode *inode, struct dentry *dentry, umode_t mode,
>                 struct TCP_Server_Info *server = tcon->ses->server;
>                 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
>                     (mode & S_IWUGO) == 0 && server->ops->mkdir_setinfo)
> -                       server->ops->mkdir_setinfo(newinode, full_path, cifs_sb,
> +                       server->ops->mkdir_setinfo(inode, full_path, cifs_sb,
>                                                    tcon, xid);
> -               if (dentry->d_inode) {
> -                       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
> -                               dentry->d_inode->i_mode = (mode | S_IFDIR);
> -
> -                       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
> -                               dentry->d_inode->i_uid = current_fsuid();
> -                               if (inode->i_mode & S_ISGID)
> -                                       dentry->d_inode->i_gid = inode->i_gid;
> -                               else
> -                                       dentry->d_inode->i_gid =
> -                                                               current_fsgid();
> -                       }
> +               if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
> +                       inode->i_mode = (mode | S_IFDIR);
> +
> +               if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
> +                       inode->i_uid = current_fsuid();
> +                       if (inode->i_mode & S_ISGID)
> +                               inode->i_gid = parent->i_gid;
> +                       else
> +                               inode->i_gid = current_fsgid();
>                 }
>         }
> +       d_instantiate(dentry, inode);
>         return rc;
>  }
>
> --
> 1.7.11.4
>

Reviewed-by: Pavel Shilovsky <piastry@xxxxxxxxxxx>

-- 
Best regards,
Pavel Shilovsky.
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux