aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/inode.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2009-06-25 00:56:52 -0400
committerSteve French <sfrench@us.ibm.com>2009-07-01 17:26:42 -0400
commitcc0bad7552308e8905d6ea56e6b7811fa67e716d (patch)
treec02a91f13a502f444330b91b36ab12f55f352268 /fs/cifs/inode.c
parentd960eea974f5e500c0dcb95a934239cc1f481cfd (diff)
cifs: add new cifs_iget function and convert unix codepath to use it
cifs: add new cifs_iget function and convert unix codepath to use it In order to unify some codepaths, introduce a common cifs_fattr struct for storing inode attributes. The different codepaths (unix, legacy, normal, etc...) can fill out this struct with inode info. It can then be passed as an arg to a common set of routines to get and update inodes. Add a new cifs_iget function that uses iget5_locked to identify inodes. This will compare inodes based on the uniqueid value in a cifs_fattr struct. Rather than filling out an already-created inode, have cifs_get_inode_info_unix instead fill out cifs_fattr and hand that off to cifs_iget. cifs_iget can then properly look for hardlinked inodes. On the readdir side, add a new cifs_readdir_lookup function that spawns populated dentries. Redefine FILE_UNIX_INFO so that it's basically a FILE_UNIX_BASIC_INFO that has a few fields wrapped around it. This allows us to more easily use the same function for filling out the fattr as the non-readdir codepath. With this, we should then have proper hardlink detection and can eventually get rid of some nasty CIFS-specific hacks for handing them. Signed-off-by: Jeff Layton <jlayton@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Steve French <sfrench@us.ibm.com>
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r--fs/cifs/inode.c380
1 files changed, 192 insertions, 188 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 155c9e785d0c..b22379610d71 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -77,127 +77,146 @@ static void cifs_set_ops(struct inode *inode, const bool is_dfs_referral)
77 } 77 }
78} 78}
79 79
80static void cifs_unix_info_to_inode(struct inode *inode, 80/* populate an inode with info from a cifs_fattr struct */
81 FILE_UNIX_BASIC_INFO *info, int force_uid_gid) 81void
82cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
82{ 83{
83 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 84 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
84 struct cifsInodeInfo *cifsInfo = CIFS_I(inode); 85 unsigned long now = jiffies;
85 __u64 num_of_bytes = le64_to_cpu(info->NumOfBytes); 86
86 __u64 end_of_file = le64_to_cpu(info->EndOfFile); 87 inode->i_atime = fattr->cf_atime;
88 inode->i_mtime = fattr->cf_mtime;
89 inode->i_ctime = fattr->cf_ctime;
90 inode->i_mode = fattr->cf_mode;
91 inode->i_rdev = fattr->cf_rdev;
92 inode->i_nlink = fattr->cf_nlink;
93 inode->i_uid = fattr->cf_uid;
94 inode->i_gid = fattr->cf_gid;
95
96 cifs_i->cifsAttrs = fattr->cf_cifsattrs;
97 cifs_i->uniqueid = fattr->cf_uniqueid;
98
99 cFYI(1, ("inode 0x%p old_time=%ld new_time=%ld", inode,
100 cifs_i->time, now));
101 cifs_i->time = now;
102
103 /*
104 * Can't safely change the file size here if the client is writing to
105 * it due to potential races.
106 */
107 spin_lock(&inode->i_lock);
108 if (is_size_safe_to_change(cifs_i, fattr->cf_eof)) {
109 i_size_write(inode, fattr->cf_eof);
110
111 /*
112 * i_blocks is not related to (i_size / i_blksize),
113 * but instead 512 byte (2**9) size is required for
114 * calculating num blocks.
115 */
116 inode->i_blocks = (512 - 1 + fattr->cf_bytes) >> 9;
117 }
118 spin_unlock(&inode->i_lock);
119
120 cifs_set_ops(inode, fattr->cf_flags & CIFS_FATTR_DFS_REFERRAL);
121}
122
123/* Fill a cifs_fattr struct with info from FILE_UNIX_BASIC_INFO. */
124void
125cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
126 struct cifs_sb_info *cifs_sb)
127{
128 memset(fattr, 0, sizeof(*fattr));
129 fattr->cf_uniqueid = le64_to_cpu(info->UniqueId);
130 fattr->cf_bytes = le64_to_cpu(info->NumOfBytes);
131 fattr->cf_eof = le64_to_cpu(info->EndOfFile);
87 132
88 inode->i_atime = cifs_NTtimeToUnix(info->LastAccessTime); 133 fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
89 inode->i_mtime = 134 fattr->cf_mtime = cifs_NTtimeToUnix(info->LastModificationTime);
90 cifs_NTtimeToUnix(info->LastModificationTime); 135 fattr->cf_ctime = cifs_NTtimeToUnix(info->LastStatusChange);
91 inode->i_ctime = cifs_NTtimeToUnix(info->LastStatusChange); 136 fattr->cf_mode = le64_to_cpu(info->Permissions);
92 inode->i_mode = le64_to_cpu(info->Permissions);
93 137
94 /* 138 /*
95 * Since we set the inode type below we need to mask off 139 * Since we set the inode type below we need to mask off
96 * to avoid strange results if bits set above. 140 * to avoid strange results if bits set above.
97 */ 141 */
98 inode->i_mode &= ~S_IFMT; 142 fattr->cf_mode &= ~S_IFMT;
99 switch (le32_to_cpu(info->Type)) { 143 switch (le32_to_cpu(info->Type)) {
100 case UNIX_FILE: 144 case UNIX_FILE:
101 inode->i_mode |= S_IFREG; 145 fattr->cf_mode |= S_IFREG;
146 fattr->cf_dtype = DT_REG;
102 break; 147 break;
103 case UNIX_SYMLINK: 148 case UNIX_SYMLINK:
104 inode->i_mode |= S_IFLNK; 149 fattr->cf_mode |= S_IFLNK;
150 fattr->cf_dtype = DT_LNK;
105 break; 151 break;
106 case UNIX_DIR: 152 case UNIX_DIR:
107 inode->i_mode |= S_IFDIR; 153 fattr->cf_mode |= S_IFDIR;
154 fattr->cf_dtype = DT_DIR;
108 break; 155 break;
109 case UNIX_CHARDEV: 156 case UNIX_CHARDEV:
110 inode->i_mode |= S_IFCHR; 157 fattr->cf_mode |= S_IFCHR;
111 inode->i_rdev = MKDEV(le64_to_cpu(info->DevMajor), 158 fattr->cf_dtype = DT_CHR;
112 le64_to_cpu(info->DevMinor) & MINORMASK); 159 fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor),
160 le64_to_cpu(info->DevMinor) & MINORMASK);
113 break; 161 break;
114 case UNIX_BLOCKDEV: 162 case UNIX_BLOCKDEV:
115 inode->i_mode |= S_IFBLK; 163 fattr->cf_mode |= S_IFBLK;
116 inode->i_rdev = MKDEV(le64_to_cpu(info->DevMajor), 164 fattr->cf_dtype = DT_BLK;
117 le64_to_cpu(info->DevMinor) & MINORMASK); 165 fattr->cf_rdev = MKDEV(le64_to_cpu(info->DevMajor),
166 le64_to_cpu(info->DevMinor) & MINORMASK);
118 break; 167 break;
119 case UNIX_FIFO: 168 case UNIX_FIFO:
120 inode->i_mode |= S_IFIFO; 169 fattr->cf_mode |= S_IFIFO;
170 fattr->cf_dtype = DT_FIFO;
121 break; 171 break;
122 case UNIX_SOCKET: 172 case UNIX_SOCKET:
123 inode->i_mode |= S_IFSOCK; 173 fattr->cf_mode |= S_IFSOCK;
174 fattr->cf_dtype = DT_SOCK;
124 break; 175 break;
125 default: 176 default:
126 /* safest to call it a file if we do not know */ 177 /* safest to call it a file if we do not know */
127 inode->i_mode |= S_IFREG; 178 fattr->cf_mode |= S_IFREG;
179 fattr->cf_dtype = DT_REG;
128 cFYI(1, ("unknown type %d", le32_to_cpu(info->Type))); 180 cFYI(1, ("unknown type %d", le32_to_cpu(info->Type)));
129 break; 181 break;
130 } 182 }
131 183
132 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) && 184 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
133 !force_uid_gid) 185 fattr->cf_uid = cifs_sb->mnt_uid;
134 inode->i_uid = cifs_sb->mnt_uid;
135 else 186 else
136 inode->i_uid = le64_to_cpu(info->Uid); 187 fattr->cf_uid = le64_to_cpu(info->Uid);
137 188
138 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) && 189 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
139 !force_uid_gid) 190 fattr->cf_gid = cifs_sb->mnt_gid;
140 inode->i_gid = cifs_sb->mnt_gid;
141 else 191 else
142 inode->i_gid = le64_to_cpu(info->Gid); 192 fattr->cf_gid = le64_to_cpu(info->Gid);
143 193
144 inode->i_nlink = le64_to_cpu(info->Nlinks); 194 fattr->cf_nlink = le64_to_cpu(info->Nlinks);
145
146 cifsInfo->server_eof = end_of_file;
147 spin_lock(&inode->i_lock);
148 if (is_size_safe_to_change(cifsInfo, end_of_file)) {
149 /*
150 * We can not safely change the file size here if the client
151 * is writing to it due to potential races.
152 */
153 i_size_write(inode, end_of_file);
154
155 /*
156 * i_blocks is not related to (i_size / i_blksize),
157 * but instead 512 byte (2**9) size is required for
158 * calculating num blocks.
159 */
160 inode->i_blocks = (512 - 1 + num_of_bytes) >> 9;
161 }
162 spin_unlock(&inode->i_lock);
163} 195}
164 196
165
166/* 197/*
167 * Needed to setup inode data for the directory which is the 198 * Fill a cifs_fattr struct with fake inode info.
168 * junction to the new submount (ie to setup the fake directory 199 *
169 * which represents a DFS referral) 200 * Needed to setup cifs_fattr data for the directory which is the
201 * junction to the new submount (ie to setup the fake directory
202 * which represents a DFS referral).
170 */ 203 */
171static void fill_fake_finddataunix(FILE_UNIX_BASIC_INFO *pfnd_dat, 204void
172 struct super_block *sb) 205cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb)
173{ 206{
174 struct inode *pinode = NULL; 207 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
175
176 memset(pfnd_dat, 0, sizeof(FILE_UNIX_BASIC_INFO));
177 208
178/* __le64 pfnd_dat->EndOfFile = cpu_to_le64(0); 209 cFYI(1, ("creating fake fattr for DFS referral"));
179 __le64 pfnd_dat->NumOfBytes = cpu_to_le64(0); 210
180 __u64 UniqueId = 0; */ 211 memset(fattr, 0, sizeof(*fattr));
181 pfnd_dat->LastStatusChange = 212 fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU;
182 cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 213 fattr->cf_uid = cifs_sb->mnt_uid;
183 pfnd_dat->LastAccessTime = 214 fattr->cf_gid = cifs_sb->mnt_gid;
184 cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 215 fattr->cf_atime = CURRENT_TIME;
185 pfnd_dat->LastModificationTime = 216 fattr->cf_ctime = CURRENT_TIME;
186 cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 217 fattr->cf_mtime = CURRENT_TIME;
187 pfnd_dat->Type = cpu_to_le32(UNIX_DIR); 218 fattr->cf_nlink = 2;
188 pfnd_dat->Permissions = cpu_to_le64(S_IXUGO | S_IRWXU); 219 fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL;
189 pfnd_dat->Nlinks = cpu_to_le64(2);
190 if (sb->s_root)
191 pinode = sb->s_root->d_inode;
192 if (pinode == NULL)
193 return;
194
195 /* fill in default values for the remaining based on root
196 inode since we can not query the server for this inode info */
197 pfnd_dat->DevMajor = cpu_to_le64(MAJOR(pinode->i_rdev));
198 pfnd_dat->DevMinor = cpu_to_le64(MINOR(pinode->i_rdev));
199 pfnd_dat->Uid = cpu_to_le64(pinode->i_uid);
200 pfnd_dat->Gid = cpu_to_le64(pinode->i_gid);
201} 220}
202 221
203/** 222/**
@@ -244,66 +263,42 @@ cifs_new_inode(struct super_block *sb, __u64 *inum)
244} 263}
245 264
246int cifs_get_inode_info_unix(struct inode **pinode, 265int cifs_get_inode_info_unix(struct inode **pinode,
247 const unsigned char *full_path, struct super_block *sb, int xid) 266 const unsigned char *full_path,
267 struct super_block *sb, int xid)
248{ 268{
249 int rc = 0; 269 int rc;
250 FILE_UNIX_BASIC_INFO find_data; 270 FILE_UNIX_BASIC_INFO find_data;
251 struct cifsTconInfo *pTcon; 271 struct cifs_fattr fattr;
252 struct inode *inode; 272 struct cifsTconInfo *tcon;
253 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 273 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
254 bool is_dfs_referral = false;
255 struct cifsInodeInfo *cifsInfo;
256 __u64 num_of_bytes;
257 __u64 end_of_file;
258 274
259 pTcon = cifs_sb->tcon; 275 tcon = cifs_sb->tcon;
260 cFYI(1, ("Getting info on %s", full_path)); 276 cFYI(1, ("Getting info on %s", full_path));
261 277
262 /* could have done a find first instead but this returns more info */ 278 /* could have done a find first instead but this returns more info */
263 rc = CIFSSMBUnixQPathInfo(xid, pTcon, full_path, &find_data, 279 rc = CIFSSMBUnixQPathInfo(xid, tcon, full_path, &find_data,
264 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 280 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
265 CIFS_MOUNT_MAP_SPECIAL_CHR); 281 CIFS_MOUNT_MAP_SPECIAL_CHR);
266 if (rc == -EREMOTE && !is_dfs_referral) {
267 is_dfs_referral = true;
268 cFYI(DBG2, ("DFS ref"));
269 /* for DFS, server does not give us real inode data */
270 fill_fake_finddataunix(&find_data, sb);
271 rc = 0;
272 } else if (rc)
273 goto cgiiu_exit;
274 282
275 num_of_bytes = le64_to_cpu(find_data.NumOfBytes); 283 if (!rc) {
276 end_of_file = le64_to_cpu(find_data.EndOfFile); 284 cifs_unix_basic_to_fattr(&fattr, &find_data, cifs_sb);
285 } else if (rc == -EREMOTE) {
286 cifs_create_dfs_fattr(&fattr, sb);
287 rc = 0;
288 } else {
289 return rc;
290 }
277 291
278 /* get new inode */
279 if (*pinode == NULL) { 292 if (*pinode == NULL) {
280 __u64 unique_id = le64_to_cpu(find_data.UniqueId); 293 /* get new inode */
281 *pinode = cifs_new_inode(sb, &unique_id); 294 *pinode = cifs_iget(sb, &fattr);
282 if (*pinode == NULL) { 295 if (!*pinode)
283 rc = -ENOMEM; 296 rc = -ENOMEM;
284 goto cgiiu_exit; 297 } else {
285 } 298 /* we already have inode, update it */
299 cifs_fattr_to_inode(*pinode, &fattr);
286 } 300 }
287 301
288 inode = *pinode;
289 cifsInfo = CIFS_I(inode);
290
291 cFYI(1, ("Old time %ld", cifsInfo->time));
292 cifsInfo->time = jiffies;
293 cFYI(1, ("New time %ld", cifsInfo->time));
294 /* this is ok to set on every inode revalidate */
295 atomic_set(&cifsInfo->inUse, 1);
296
297 cifs_unix_info_to_inode(inode, &find_data, 0);
298
299 if (num_of_bytes < end_of_file)
300 cFYI(1, ("allocation size less than end of file"));
301 cFYI(1, ("Size %ld and blocks %llu",
302 (unsigned long) inode->i_size,
303 (unsigned long long)inode->i_blocks));
304
305 cifs_set_ops(inode, is_dfs_referral);
306cgiiu_exit:
307 return rc; 302 return rc;
308} 303}
309 304
@@ -695,33 +690,85 @@ char *cifs_build_path_to_root(struct cifs_sb_info *cifs_sb)
695 return full_path; 690 return full_path;
696} 691}
697 692
693static int
694cifs_find_inode(struct inode *inode, void *opaque)
695{
696 struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;
697
698 if (CIFS_I(inode)->uniqueid != fattr->cf_uniqueid)
699 return 0;
700
701 return 1;
702}
703
704static int
705cifs_init_inode(struct inode *inode, void *opaque)
706{
707 struct cifs_fattr *fattr = (struct cifs_fattr *) opaque;
708
709 CIFS_I(inode)->uniqueid = fattr->cf_uniqueid;
710 return 0;
711}
712
713/* Given fattrs, get a corresponding inode */
714struct inode *
715cifs_iget(struct super_block *sb, struct cifs_fattr *fattr)
716{
717 unsigned long hash;
718 struct inode *inode;
719
720 cFYI(1, ("looking for uniqueid=%llu", fattr->cf_uniqueid));
721
722 /* hash down to 32-bits on 32-bit arch */
723 hash = cifs_uniqueid_to_ino_t(fattr->cf_uniqueid);
724
725 inode = iget5_locked(sb, hash, cifs_find_inode, cifs_init_inode, fattr);
726
727 /* we have fattrs in hand, update the inode */
728 if (inode) {
729 cifs_fattr_to_inode(inode, fattr);
730 if (sb->s_flags & MS_NOATIME)
731 inode->i_flags |= S_NOATIME | S_NOCMTIME;
732 if (inode->i_state & I_NEW) {
733 inode->i_ino = hash;
734 unlock_new_inode(inode);
735 }
736 }
737
738 return inode;
739}
740
698/* gets root inode */ 741/* gets root inode */
699struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino) 742struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
700{ 743{
701 int xid; 744 int xid;
702 struct cifs_sb_info *cifs_sb; 745 struct cifs_sb_info *cifs_sb;
703 struct inode *inode; 746 struct inode *inode = NULL;
704 long rc; 747 long rc;
705 char *full_path; 748 char *full_path;
706 749
707 inode = iget_locked(sb, ino); 750 cifs_sb = CIFS_SB(sb);
708 if (!inode)
709 return ERR_PTR(-ENOMEM);
710 if (!(inode->i_state & I_NEW))
711 return inode;
712
713 cifs_sb = CIFS_SB(inode->i_sb);
714 full_path = cifs_build_path_to_root(cifs_sb); 751 full_path = cifs_build_path_to_root(cifs_sb);
715 if (full_path == NULL) 752 if (full_path == NULL)
716 return ERR_PTR(-ENOMEM); 753 return ERR_PTR(-ENOMEM);
717 754
718 xid = GetXid(); 755 xid = GetXid();
719 if (cifs_sb->tcon->unix_ext) 756 if (cifs_sb->tcon->unix_ext) {
720 rc = cifs_get_inode_info_unix(&inode, full_path, inode->i_sb, 757 rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
721 xid); 758 if (!inode)
722 else 759 return ERR_PTR(-ENOMEM);
760 } else {
761 inode = iget_locked(sb, ino);
762 if (!inode)
763 return ERR_PTR(-ENOMEM);
764 if (!(inode->i_state & I_NEW))
765 return inode;
766
723 rc = cifs_get_inode_info(&inode, full_path, NULL, inode->i_sb, 767 rc = cifs_get_inode_info(&inode, full_path, NULL, inode->i_sb,
724 xid, NULL); 768 xid, NULL);
769 unlock_new_inode(inode);
770 }
771
725 if (rc && cifs_sb->tcon->ipc) { 772 if (rc && cifs_sb->tcon->ipc) {
726 cFYI(1, ("ipc connection - fake read inode")); 773 cFYI(1, ("ipc connection - fake read inode"));
727 inode->i_mode |= S_IFDIR; 774 inode->i_mode |= S_IFDIR;
@@ -737,7 +784,6 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
737 return ERR_PTR(rc); 784 return ERR_PTR(rc);
738 } 785 }
739 786
740 unlock_new_inode(inode);
741 787
742 kfree(full_path); 788 kfree(full_path);
743 /* can not call macro FreeXid here since in a void func 789 /* can not call macro FreeXid here since in a void func
@@ -1063,44 +1109,6 @@ out_reval:
1063 return rc; 1109 return rc;
1064} 1110}
1065 1111
1066void posix_fill_in_inode(struct inode *tmp_inode,
1067 FILE_UNIX_BASIC_INFO *pData, int isNewInode)
1068{
1069 struct cifsInodeInfo *cifsInfo = CIFS_I(tmp_inode);
1070 loff_t local_size;
1071 struct timespec local_mtime;
1072
1073 cifsInfo->time = jiffies;
1074 atomic_inc(&cifsInfo->inUse);
1075
1076 /* save mtime and size */
1077 local_mtime = tmp_inode->i_mtime;
1078 local_size = tmp_inode->i_size;
1079
1080 cifs_unix_info_to_inode(tmp_inode, pData, 1);
1081 cifs_set_ops(tmp_inode, false);
1082
1083 if (!S_ISREG(tmp_inode->i_mode))
1084 return;
1085
1086 /*
1087 * No sense invalidating pages for new inode
1088 * since we we have not started caching
1089 * readahead file data yet.
1090 */
1091 if (isNewInode)
1092 return;
1093
1094 if (timespec_equal(&tmp_inode->i_mtime, &local_mtime) &&
1095 (local_size == tmp_inode->i_size)) {
1096 cFYI(1, ("inode exists but unchanged"));
1097 } else {
1098 /* file may have changed on server */
1099 cFYI(1, ("invalidate inode, readdir detected change"));
1100 invalidate_remote_inode(tmp_inode);
1101 }
1102}
1103
1104int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) 1112int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
1105{ 1113{
1106 int rc = 0, tmprc; 1114 int rc = 0, tmprc;
@@ -1109,6 +1117,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
1109 struct cifsTconInfo *pTcon; 1117 struct cifsTconInfo *pTcon;
1110 char *full_path = NULL; 1118 char *full_path = NULL;
1111 struct inode *newinode = NULL; 1119 struct inode *newinode = NULL;
1120 struct cifs_fattr fattr;
1112 1121
1113 cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode)); 1122 cFYI(1, ("In cifs_mkdir, mode = 0x%x inode = 0x%p", mode, inode));
1114 1123
@@ -1148,7 +1157,6 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
1148 cFYI(1, ("posix mkdir returned 0x%x", rc)); 1157 cFYI(1, ("posix mkdir returned 0x%x", rc));
1149 d_drop(direntry); 1158 d_drop(direntry);
1150 } else { 1159 } else {
1151 __u64 unique_id;
1152 if (pInfo->Type == cpu_to_le32(-1)) { 1160 if (pInfo->Type == cpu_to_le32(-1)) {
1153 /* no return info, go query for it */ 1161 /* no return info, go query for it */
1154 kfree(pInfo); 1162 kfree(pInfo);
@@ -1162,20 +1170,15 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
1162 else 1170 else
1163 direntry->d_op = &cifs_dentry_ops; 1171 direntry->d_op = &cifs_dentry_ops;
1164 1172
1165 unique_id = le64_to_cpu(pInfo->UniqueId); 1173 cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb);
1166 newinode = cifs_new_inode(inode->i_sb, &unique_id); 1174 newinode = cifs_iget(inode->i_sb, &fattr);
1167 if (newinode == NULL) { 1175 if (!newinode) {
1168 kfree(pInfo); 1176 kfree(pInfo);
1169 goto mkdir_get_info; 1177 goto mkdir_get_info;
1170 } 1178 }
1171 1179
1172 newinode->i_nlink = 2;
1173 d_instantiate(direntry, newinode); 1180 d_instantiate(direntry, newinode);
1174 1181
1175 /* we already checked in POSIXCreate whether
1176 frame was long enough */
1177 posix_fill_in_inode(direntry->d_inode,
1178 pInfo, 1 /* NewInode */);
1179#ifdef CONFIG_CIFS_DEBUG2 1182#ifdef CONFIG_CIFS_DEBUG2
1180 cFYI(1, ("instantiated dentry %p %s to inode %p", 1183 cFYI(1, ("instantiated dentry %p %s to inode %p",
1181 direntry, direntry->d_name.name, newinode)); 1184 direntry, direntry->d_name.name, newinode));
@@ -1622,6 +1625,7 @@ int cifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
1622 if (!err) { 1625 if (!err) {
1623 generic_fillattr(dentry->d_inode, stat); 1626 generic_fillattr(dentry->d_inode, stat);
1624 stat->blksize = CIFS_MAX_MSGSIZE; 1627 stat->blksize = CIFS_MAX_MSGSIZE;
1628 stat->ino = CIFS_I(dentry->d_inode)->uniqueid;
1625 } 1629 }
1626 return err; 1630 return err;
1627} 1631}