aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2012-09-19 09:22:45 -0400
committerSteve French <smfrench@gmail.com>2012-09-24 22:46:34 -0400
commit101b92d9590a645d6fb643654b3a92556203b745 (patch)
treefb5e6ce303a74fae0bcca5904e39d0ca9d403c5b /fs/cifs
parent233839b1df65a24c8b67b748fe7b18d86d0ad6d7 (diff)
cifs: cleanups for cifs_mkdir_qinfo
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. Reviewed-by: Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs')
-rw-r--r--fs/cifs/inode.c51
1 files changed, 24 insertions, 27 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index e74e1bceb416..3d155875f446 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1177,34 +1177,33 @@ unlink_out:
1177} 1177}
1178 1178
1179static int 1179static int
1180cifs_mkdir_qinfo(struct inode *inode, struct dentry *dentry, umode_t mode, 1180cifs_mkdir_qinfo(struct inode *parent, struct dentry *dentry, umode_t mode,
1181 const char *full_path, struct cifs_sb_info *cifs_sb, 1181 const char *full_path, struct cifs_sb_info *cifs_sb,
1182 struct cifs_tcon *tcon, const unsigned int xid) 1182 struct cifs_tcon *tcon, const unsigned int xid)
1183{ 1183{
1184 int rc = 0; 1184 int rc = 0;
1185 struct inode *newinode = NULL; 1185 struct inode *inode = NULL;
1186 1186
1187 if (tcon->unix_ext) 1187 if (tcon->unix_ext)
1188 rc = cifs_get_inode_info_unix(&newinode, full_path, inode->i_sb, 1188 rc = cifs_get_inode_info_unix(&inode, full_path, parent->i_sb,
1189 xid); 1189 xid);
1190 else 1190 else
1191 rc = cifs_get_inode_info(&newinode, full_path, NULL, 1191 rc = cifs_get_inode_info(&inode, full_path, NULL, parent->i_sb,
1192 inode->i_sb, xid, NULL); 1192 xid, NULL);
1193
1193 if (rc) 1194 if (rc)
1194 return rc; 1195 return rc;
1195 1196
1196 d_instantiate(dentry, newinode);
1197 /* 1197 /*
1198 * setting nlink not necessary except in cases where we failed to get it 1198 * setting nlink not necessary except in cases where we failed to get it
1199 * from the server or was set bogus 1199 * from the server or was set bogus. Also, since this is a brand new
1200 * inode, no need to grab the i_lock before setting the i_nlink.
1200 */ 1201 */
1201 spin_lock(&dentry->d_inode->i_lock); 1202 if (inode->i_nlink < 2)
1202 if ((dentry->d_inode) && (dentry->d_inode->i_nlink < 2)) 1203 set_nlink(inode, 2);
1203 set_nlink(dentry->d_inode, 2);
1204 spin_unlock(&dentry->d_inode->i_lock);
1205 mode &= ~current_umask(); 1204 mode &= ~current_umask();
1206 /* must turn on setgid bit if parent dir has it */ 1205 /* must turn on setgid bit if parent dir has it */
1207 if (inode->i_mode & S_ISGID) 1206 if (parent->i_mode & S_ISGID)
1208 mode |= S_ISGID; 1207 mode |= S_ISGID;
1209 1208
1210 if (tcon->unix_ext) { 1209 if (tcon->unix_ext) {
@@ -1217,8 +1216,8 @@ cifs_mkdir_qinfo(struct inode *inode, struct dentry *dentry, umode_t mode,
1217 }; 1216 };
1218 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 1217 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
1219 args.uid = (__u64)current_fsuid(); 1218 args.uid = (__u64)current_fsuid();
1220 if (inode->i_mode & S_ISGID) 1219 if (parent->i_mode & S_ISGID)
1221 args.gid = (__u64)inode->i_gid; 1220 args.gid = (__u64)parent->i_gid;
1222 else 1221 else
1223 args.gid = (__u64)current_fsgid(); 1222 args.gid = (__u64)current_fsgid();
1224 } else { 1223 } else {
@@ -1233,22 +1232,20 @@ cifs_mkdir_qinfo(struct inode *inode, struct dentry *dentry, umode_t mode,
1233 struct TCP_Server_Info *server = tcon->ses->server; 1232 struct TCP_Server_Info *server = tcon->ses->server;
1234 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) && 1233 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) &&
1235 (mode & S_IWUGO) == 0 && server->ops->mkdir_setinfo) 1234 (mode & S_IWUGO) == 0 && server->ops->mkdir_setinfo)
1236 server->ops->mkdir_setinfo(newinode, full_path, cifs_sb, 1235 server->ops->mkdir_setinfo(inode, full_path, cifs_sb,
1237 tcon, xid); 1236 tcon, xid);
1238 if (dentry->d_inode) { 1237 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)
1239 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) 1238 inode->i_mode = (mode | S_IFDIR);
1240 dentry->d_inode->i_mode = (mode | S_IFDIR); 1239
1241 1240 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) {
1242 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { 1241 inode->i_uid = current_fsuid();
1243 dentry->d_inode->i_uid = current_fsuid(); 1242 if (inode->i_mode & S_ISGID)
1244 if (inode->i_mode & S_ISGID) 1243 inode->i_gid = parent->i_gid;
1245 dentry->d_inode->i_gid = inode->i_gid; 1244 else
1246 else 1245 inode->i_gid = current_fsgid();
1247 dentry->d_inode->i_gid =
1248 current_fsgid();
1249 }
1250 } 1246 }
1251 } 1247 }
1248 d_instantiate(dentry, inode);
1252 return rc; 1249 return rc;
1253} 1250}
1254 1251