aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/inode.c')
-rw-r--r--fs/cifs/inode.c397
1 files changed, 151 insertions, 246 deletions
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 55b616bb381e..a807397f444e 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -82,23 +82,34 @@ void
82cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) 82cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
83{ 83{
84 struct cifsInodeInfo *cifs_i = CIFS_I(inode); 84 struct cifsInodeInfo *cifs_i = CIFS_I(inode);
85 unsigned long now = jiffies; 85 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
86 unsigned long oldtime = cifs_i->time;
86 87
87 inode->i_atime = fattr->cf_atime; 88 inode->i_atime = fattr->cf_atime;
88 inode->i_mtime = fattr->cf_mtime; 89 inode->i_mtime = fattr->cf_mtime;
89 inode->i_ctime = fattr->cf_ctime; 90 inode->i_ctime = fattr->cf_ctime;
90 inode->i_mode = fattr->cf_mode;
91 inode->i_rdev = fattr->cf_rdev; 91 inode->i_rdev = fattr->cf_rdev;
92 inode->i_nlink = fattr->cf_nlink; 92 inode->i_nlink = fattr->cf_nlink;
93 inode->i_uid = fattr->cf_uid; 93 inode->i_uid = fattr->cf_uid;
94 inode->i_gid = fattr->cf_gid; 94 inode->i_gid = fattr->cf_gid;
95 95
96 /* if dynperm is set, don't clobber existing mode */
97 if (inode->i_state & I_NEW ||
98 !(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM))
99 inode->i_mode = fattr->cf_mode;
100
96 cifs_i->cifsAttrs = fattr->cf_cifsattrs; 101 cifs_i->cifsAttrs = fattr->cf_cifsattrs;
97 cifs_i->uniqueid = fattr->cf_uniqueid; 102 cifs_i->uniqueid = fattr->cf_uniqueid;
98 103
104 if (fattr->cf_flags & CIFS_FATTR_NEED_REVAL)
105 cifs_i->time = 0;
106 else
107 cifs_i->time = jiffies;
108
99 cFYI(1, ("inode 0x%p old_time=%ld new_time=%ld", inode, 109 cFYI(1, ("inode 0x%p old_time=%ld new_time=%ld", inode,
100 cifs_i->time, now)); 110 oldtime, cifs_i->time));
101 cifs_i->time = now; 111
112 cifs_i->delete_pending = fattr->cf_flags & CIFS_FATTR_DELETE_PENDING;
102 113
103 /* 114 /*
104 * Can't safely change the file size here if the client is writing to 115 * Can't safely change the file size here if the client is writing to
@@ -219,49 +230,6 @@ cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb)
219 fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL; 230 fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL;
220} 231}
221 232
222/**
223 * cifs_new inode - create new inode, initialize, and hash it
224 * @sb - pointer to superblock
225 * @inum - if valid pointer and serverino is enabled, replace i_ino with val
226 *
227 * Create a new inode, initialize it for CIFS and hash it. Returns the new
228 * inode or NULL if one couldn't be allocated.
229 *
230 * If the share isn't mounted with "serverino" or inum is a NULL pointer then
231 * we'll just use the inode number assigned by new_inode(). Note that this can
232 * mean i_ino collisions since the i_ino assigned by new_inode is not
233 * guaranteed to be unique.
234 */
235struct inode *
236cifs_new_inode(struct super_block *sb, __u64 *inum)
237{
238 struct inode *inode;
239
240 inode = new_inode(sb);
241 if (inode == NULL)
242 return NULL;
243
244 /*
245 * BB: Is i_ino == 0 legal? Here, we assume that it is. If it isn't we
246 * stop passing inum as ptr. Are there sanity checks we can use to
247 * ensure that the server is really filling in that field? Also,
248 * if serverino is disabled, perhaps we should be using iunique()?
249 */
250 if (inum && (CIFS_SB(sb)->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM))
251 inode->i_ino = (unsigned long) *inum;
252
253 /*
254 * must set this here instead of cifs_alloc_inode since VFS will
255 * clobber i_flags
256 */
257 if (sb->s_flags & MS_NOATIME)
258 inode->i_flags |= S_NOATIME | S_NOCMTIME;
259
260 insert_inode_hash(inode);
261
262 return inode;
263}
264
265int cifs_get_inode_info_unix(struct inode **pinode, 233int cifs_get_inode_info_unix(struct inode **pinode,
266 const unsigned char *full_path, 234 const unsigned char *full_path,
267 struct super_block *sb, int xid) 235 struct super_block *sb, int xid)
@@ -302,9 +270,9 @@ int cifs_get_inode_info_unix(struct inode **pinode,
302 return rc; 270 return rc;
303} 271}
304 272
305static int decode_sfu_inode(struct inode *inode, __u64 size, 273static int
306 const unsigned char *path, 274cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
307 struct cifs_sb_info *cifs_sb, int xid) 275 struct cifs_sb_info *cifs_sb, int xid)
308{ 276{
309 int rc; 277 int rc;
310 int oplock = 0; 278 int oplock = 0;
@@ -316,10 +284,15 @@ static int decode_sfu_inode(struct inode *inode, __u64 size,
316 284
317 pbuf = buf; 285 pbuf = buf;
318 286
319 if (size == 0) { 287 fattr->cf_mode &= ~S_IFMT;
320 inode->i_mode |= S_IFIFO; 288
289 if (fattr->cf_eof == 0) {
290 fattr->cf_mode |= S_IFIFO;
291 fattr->cf_dtype = DT_FIFO;
321 return 0; 292 return 0;
322 } else if (size < 8) { 293 } else if (fattr->cf_eof < 8) {
294 fattr->cf_mode |= S_IFREG;
295 fattr->cf_dtype = DT_REG;
323 return -EINVAL; /* EOPNOTSUPP? */ 296 return -EINVAL; /* EOPNOTSUPP? */
324 } 297 }
325 298
@@ -331,42 +304,46 @@ static int decode_sfu_inode(struct inode *inode, __u64 size,
331 if (rc == 0) { 304 if (rc == 0) {
332 int buf_type = CIFS_NO_BUFFER; 305 int buf_type = CIFS_NO_BUFFER;
333 /* Read header */ 306 /* Read header */
334 rc = CIFSSMBRead(xid, pTcon, 307 rc = CIFSSMBRead(xid, pTcon, netfid,
335 netfid,
336 24 /* length */, 0 /* offset */, 308 24 /* length */, 0 /* offset */,
337 &bytes_read, &pbuf, &buf_type); 309 &bytes_read, &pbuf, &buf_type);
338 if ((rc == 0) && (bytes_read >= 8)) { 310 if ((rc == 0) && (bytes_read >= 8)) {
339 if (memcmp("IntxBLK", pbuf, 8) == 0) { 311 if (memcmp("IntxBLK", pbuf, 8) == 0) {
340 cFYI(1, ("Block device")); 312 cFYI(1, ("Block device"));
341 inode->i_mode |= S_IFBLK; 313 fattr->cf_mode |= S_IFBLK;
314 fattr->cf_dtype = DT_BLK;
342 if (bytes_read == 24) { 315 if (bytes_read == 24) {
343 /* we have enough to decode dev num */ 316 /* we have enough to decode dev num */
344 __u64 mjr; /* major */ 317 __u64 mjr; /* major */
345 __u64 mnr; /* minor */ 318 __u64 mnr; /* minor */
346 mjr = le64_to_cpu(*(__le64 *)(pbuf+8)); 319 mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
347 mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); 320 mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
348 inode->i_rdev = MKDEV(mjr, mnr); 321 fattr->cf_rdev = MKDEV(mjr, mnr);
349 } 322 }
350 } else if (memcmp("IntxCHR", pbuf, 8) == 0) { 323 } else if (memcmp("IntxCHR", pbuf, 8) == 0) {
351 cFYI(1, ("Char device")); 324 cFYI(1, ("Char device"));
352 inode->i_mode |= S_IFCHR; 325 fattr->cf_mode |= S_IFCHR;
326 fattr->cf_dtype = DT_CHR;
353 if (bytes_read == 24) { 327 if (bytes_read == 24) {
354 /* we have enough to decode dev num */ 328 /* we have enough to decode dev num */
355 __u64 mjr; /* major */ 329 __u64 mjr; /* major */
356 __u64 mnr; /* minor */ 330 __u64 mnr; /* minor */
357 mjr = le64_to_cpu(*(__le64 *)(pbuf+8)); 331 mjr = le64_to_cpu(*(__le64 *)(pbuf+8));
358 mnr = le64_to_cpu(*(__le64 *)(pbuf+16)); 332 mnr = le64_to_cpu(*(__le64 *)(pbuf+16));
359 inode->i_rdev = MKDEV(mjr, mnr); 333 fattr->cf_rdev = MKDEV(mjr, mnr);
360 } 334 }
361 } else if (memcmp("IntxLNK", pbuf, 7) == 0) { 335 } else if (memcmp("IntxLNK", pbuf, 7) == 0) {
362 cFYI(1, ("Symlink")); 336 cFYI(1, ("Symlink"));
363 inode->i_mode |= S_IFLNK; 337 fattr->cf_mode |= S_IFLNK;
338 fattr->cf_dtype = DT_LNK;
364 } else { 339 } else {
365 inode->i_mode |= S_IFREG; /* file? */ 340 fattr->cf_mode |= S_IFREG; /* file? */
341 fattr->cf_dtype = DT_REG;
366 rc = -EOPNOTSUPP; 342 rc = -EOPNOTSUPP;
367 } 343 }
368 } else { 344 } else {
369 inode->i_mode |= S_IFREG; /* then it is a file */ 345 fattr->cf_mode |= S_IFREG; /* then it is a file */
346 fattr->cf_dtype = DT_REG;
370 rc = -EOPNOTSUPP; /* or some unknown SFU type */ 347 rc = -EOPNOTSUPP; /* or some unknown SFU type */
371 } 348 }
372 CIFSSMBClose(xid, pTcon, netfid); 349 CIFSSMBClose(xid, pTcon, netfid);
@@ -376,9 +353,13 @@ static int decode_sfu_inode(struct inode *inode, __u64 size,
376 353
377#define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */ 354#define SFBITS_MASK (S_ISVTX | S_ISGID | S_ISUID) /* SETFILEBITS valid bits */
378 355
379static int get_sfu_mode(struct inode *inode, 356/*
380 const unsigned char *path, 357 * Fetch mode bits as provided by SFU.
381 struct cifs_sb_info *cifs_sb, int xid) 358 *
359 * FIXME: Doesn't this clobber the type bit we got from cifs_sfu_type ?
360 */
361static int cifs_sfu_mode(struct cifs_fattr *fattr, const unsigned char *path,
362 struct cifs_sb_info *cifs_sb, int xid)
382{ 363{
383#ifdef CONFIG_CIFS_XATTR 364#ifdef CONFIG_CIFS_XATTR
384 ssize_t rc; 365 ssize_t rc;
@@ -386,68 +367,80 @@ static int get_sfu_mode(struct inode *inode,
386 __u32 mode; 367 __u32 mode;
387 368
388 rc = CIFSSMBQueryEA(xid, cifs_sb->tcon, path, "SETFILEBITS", 369 rc = CIFSSMBQueryEA(xid, cifs_sb->tcon, path, "SETFILEBITS",
389 ea_value, 4 /* size of buf */, cifs_sb->local_nls, 370 ea_value, 4 /* size of buf */, cifs_sb->local_nls,
390 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 371 cifs_sb->mnt_cifs_flags &
372 CIFS_MOUNT_MAP_SPECIAL_CHR);
391 if (rc < 0) 373 if (rc < 0)
392 return (int)rc; 374 return (int)rc;
393 else if (rc > 3) { 375 else if (rc > 3) {
394 mode = le32_to_cpu(*((__le32 *)ea_value)); 376 mode = le32_to_cpu(*((__le32 *)ea_value));
395 inode->i_mode &= ~SFBITS_MASK; 377 fattr->cf_mode &= ~SFBITS_MASK;
396 cFYI(1, ("special bits 0%o org mode 0%o", mode, inode->i_mode)); 378 cFYI(1, ("special bits 0%o org mode 0%o", mode,
397 inode->i_mode = (mode & SFBITS_MASK) | inode->i_mode; 379 fattr->cf_mode));
380 fattr->cf_mode = (mode & SFBITS_MASK) | fattr->cf_mode;
398 cFYI(1, ("special mode bits 0%o", mode)); 381 cFYI(1, ("special mode bits 0%o", mode));
399 return 0;
400 } else {
401 return 0;
402 } 382 }
383
384 return 0;
403#else 385#else
404 return -EOPNOTSUPP; 386 return -EOPNOTSUPP;
405#endif 387#endif
406} 388}
407 389
408/* 390/* Fill a cifs_fattr struct with info from FILE_ALL_INFO */
409 * Needed to setup inode data for the directory which is the 391void
410 * junction to the new submount (ie to setup the fake directory 392cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
411 * which represents a DFS referral) 393 struct cifs_sb_info *cifs_sb, bool adjust_tz)
412 */
413static void fill_fake_finddata(FILE_ALL_INFO *pfnd_dat,
414 struct super_block *sb)
415{ 394{
416 memset(pfnd_dat, 0, sizeof(FILE_ALL_INFO)); 395 memset(fattr, 0, sizeof(*fattr));
417 396 fattr->cf_cifsattrs = le32_to_cpu(info->Attributes);
418/* __le64 pfnd_dat->AllocationSize = cpu_to_le64(0); 397 if (info->DeletePending)
419 __le64 pfnd_dat->EndOfFile = cpu_to_le64(0); 398 fattr->cf_flags |= CIFS_FATTR_DELETE_PENDING;
420 __u8 pfnd_dat->DeletePending = 0; 399
421 __u8 pfnd_data->Directory = 0; 400 if (info->LastAccessTime)
422 __le32 pfnd_dat->EASize = 0; 401 fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
423 __u64 pfnd_dat->IndexNumber = 0; 402 else
424 __u64 pfnd_dat->IndexNumber1 = 0; */ 403 fattr->cf_atime = CURRENT_TIME;
425 pfnd_dat->CreationTime = 404
426 cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 405 fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime);
427 pfnd_dat->LastAccessTime = 406 fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime);
428 cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 407
429 pfnd_dat->LastWriteTime = 408 if (adjust_tz) {
430 cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 409 fattr->cf_ctime.tv_sec += cifs_sb->tcon->ses->server->timeAdj;
431 pfnd_dat->ChangeTime = 410 fattr->cf_mtime.tv_sec += cifs_sb->tcon->ses->server->timeAdj;
432 cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME)); 411 }
433 pfnd_dat->Attributes = cpu_to_le32(ATTR_DIRECTORY); 412
434 pfnd_dat->NumberOfLinks = cpu_to_le32(2); 413 fattr->cf_eof = le64_to_cpu(info->EndOfFile);
414 fattr->cf_bytes = le64_to_cpu(info->AllocationSize);
415
416 if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
417 fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode;
418 fattr->cf_dtype = DT_DIR;
419 } else {
420 fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode;
421 fattr->cf_dtype = DT_REG;
422 }
423
424 /* clear write bits if ATTR_READONLY is set */
425 if (fattr->cf_cifsattrs & ATTR_READONLY)
426 fattr->cf_mode &= ~(S_IWUGO);
427
428 fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks);
429
430 fattr->cf_uid = cifs_sb->mnt_uid;
431 fattr->cf_gid = cifs_sb->mnt_gid;
435} 432}
436 433
437int cifs_get_inode_info(struct inode **pinode, 434int cifs_get_inode_info(struct inode **pinode,
438 const unsigned char *full_path, FILE_ALL_INFO *pfindData, 435 const unsigned char *full_path, FILE_ALL_INFO *pfindData,
439 struct super_block *sb, int xid, const __u16 *pfid) 436 struct super_block *sb, int xid, const __u16 *pfid)
440{ 437{
441 int rc = 0; 438 int rc = 0, tmprc;
442 __u32 attr;
443 struct cifsInodeInfo *cifsInfo;
444 struct cifsTconInfo *pTcon; 439 struct cifsTconInfo *pTcon;
445 struct inode *inode;
446 struct cifs_sb_info *cifs_sb = CIFS_SB(sb); 440 struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
447 char *buf = NULL; 441 char *buf = NULL;
448 bool adjustTZ = false; 442 bool adjustTZ = false;
449 bool is_dfs_referral = false; 443 struct cifs_fattr fattr;
450 umode_t default_mode;
451 444
452 pTcon = cifs_sb->tcon; 445 pTcon = cifs_sb->tcon;
453 cFYI(1, ("Getting info on %s", full_path)); 446 cFYI(1, ("Getting info on %s", full_path));
@@ -482,163 +475,82 @@ int cifs_get_inode_info(struct inode **pinode,
482 adjustTZ = true; 475 adjustTZ = true;
483 } 476 }
484 } 477 }
485 /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */ 478
486 if (rc == -EREMOTE) { 479 if (!rc) {
487 is_dfs_referral = true; 480 cifs_all_info_to_fattr(&fattr, (FILE_ALL_INFO *) pfindData,
488 fill_fake_finddata(pfindData, sb); 481 cifs_sb, adjustTZ);
482 } else if (rc == -EREMOTE) {
483 cifs_create_dfs_fattr(&fattr, sb);
489 rc = 0; 484 rc = 0;
490 } else if (rc) 485 } else {
491 goto cgii_exit; 486 goto cgii_exit;
487 }
492 488
493 attr = le32_to_cpu(pfindData->Attributes); 489 /*
494 490 * If an inode wasn't passed in, then get the inode number
495 /* get new inode */ 491 *
492 * Is an i_ino of zero legal? Can we use that to check if the server
493 * supports returning inode numbers? Are there other sanity checks we
494 * can use to ensure that the server is really filling in that field?
495 *
496 * We can not use the IndexNumber field by default from Windows or
497 * Samba (in ALL_INFO buf) but we can request it explicitly. The SNIA
498 * CIFS spec claims that this value is unique within the scope of a
499 * share, and the windows docs hint that it's actually unique
500 * per-machine.
501 *
502 * There may be higher info levels that work but are there Windows
503 * server or network appliances for which IndexNumber field is not
504 * guaranteed unique?
505 */
496 if (*pinode == NULL) { 506 if (*pinode == NULL) {
497 __u64 inode_num;
498 __u64 *pinum = &inode_num;
499
500 /* Is an i_ino of zero legal? Can we use that to check
501 if the server supports returning inode numbers? Are
502 there other sanity checks we can use to ensure that
503 the server is really filling in that field? */
504
505 /* We can not use the IndexNumber field by default from
506 Windows or Samba (in ALL_INFO buf) but we can request
507 it explicitly. It may not be unique presumably if
508 the server has multiple devices mounted under one share */
509
510 /* There may be higher info levels that work but are
511 there Windows server or network appliances for which
512 IndexNumber field is not guaranteed unique? */
513
514 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) { 507 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
515 int rc1 = 0; 508 int rc1 = 0;
516 509
517 rc1 = CIFSGetSrvInodeNumber(xid, pTcon, 510 rc1 = CIFSGetSrvInodeNumber(xid, pTcon,
518 full_path, pinum, 511 full_path, &fattr.cf_uniqueid,
519 cifs_sb->local_nls, 512 cifs_sb->local_nls,
520 cifs_sb->mnt_cifs_flags & 513 cifs_sb->mnt_cifs_flags &
521 CIFS_MOUNT_MAP_SPECIAL_CHR); 514 CIFS_MOUNT_MAP_SPECIAL_CHR);
522 if (rc1) { 515 if (rc1) {
523 cFYI(1, ("GetSrvInodeNum rc %d", rc1));
524 pinum = NULL;
525 /* BB EOPNOSUPP disable SERVER_INUM? */ 516 /* BB EOPNOSUPP disable SERVER_INUM? */
517 cFYI(1, ("GetSrvInodeNum rc %d", rc1));
518 fattr.cf_uniqueid = iunique(sb, ROOT_I);
526 } 519 }
527 } else { 520 } else {
528 pinum = NULL; 521 fattr.cf_uniqueid = iunique(sb, ROOT_I);
529 } 522 }
530
531 *pinode = cifs_new_inode(sb, pinum);
532 if (*pinode == NULL) {
533 rc = -ENOMEM;
534 goto cgii_exit;
535 }
536 }
537 inode = *pinode;
538 cifsInfo = CIFS_I(inode);
539 cifsInfo->cifsAttrs = attr;
540 cifsInfo->delete_pending = pfindData->DeletePending ? true : false;
541 cFYI(1, ("Old time %ld", cifsInfo->time));
542 cifsInfo->time = jiffies;
543 cFYI(1, ("New time %ld", cifsInfo->time));
544
545 /* blksize needs to be multiple of two. So safer to default to
546 blksize and blkbits set in superblock so 2**blkbits and blksize
547 will match rather than setting to:
548 (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;*/
549
550 /* Linux can not store file creation time so ignore it */
551 if (pfindData->LastAccessTime)
552 inode->i_atime = cifs_NTtimeToUnix(pfindData->LastAccessTime);
553 else /* do not need to use current_fs_time - time not stored */
554 inode->i_atime = CURRENT_TIME;
555 inode->i_mtime = cifs_NTtimeToUnix(pfindData->LastWriteTime);
556 inode->i_ctime = cifs_NTtimeToUnix(pfindData->ChangeTime);
557 cFYI(DBG2, ("Attributes came in as 0x%x", attr));
558 if (adjustTZ && (pTcon->ses) && (pTcon->ses->server)) {
559 inode->i_ctime.tv_sec += pTcon->ses->server->timeAdj;
560 inode->i_mtime.tv_sec += pTcon->ses->server->timeAdj;
561 }
562
563 /* get default inode mode */
564 if (attr & ATTR_DIRECTORY)
565 default_mode = cifs_sb->mnt_dir_mode;
566 else
567 default_mode = cifs_sb->mnt_file_mode;
568
569 /* set permission bits */
570 if (atomic_read(&cifsInfo->inUse) == 0 ||
571 (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) == 0)
572 inode->i_mode = default_mode;
573 else {
574 /* just reenable write bits if !ATTR_READONLY */
575 if ((inode->i_mode & S_IWUGO) == 0 &&
576 (attr & ATTR_READONLY) == 0)
577 inode->i_mode |= (S_IWUGO & default_mode);
578
579 inode->i_mode &= ~S_IFMT;
580 }
581 /* clear write bits if ATTR_READONLY is set */
582 if (attr & ATTR_READONLY)
583 inode->i_mode &= ~S_IWUGO;
584
585 /* set inode type */
586 if ((attr & ATTR_SYSTEM) &&
587 (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)) {
588 /* no need to fix endianness on 0 */
589 if (pfindData->EndOfFile == 0)
590 inode->i_mode |= S_IFIFO;
591 else if (decode_sfu_inode(inode,
592 le64_to_cpu(pfindData->EndOfFile),
593 full_path, cifs_sb, xid))
594 cFYI(1, ("unknown SFU file type\n"));
595 } else { 523 } else {
596 if (attr & ATTR_DIRECTORY) 524 fattr.cf_uniqueid = CIFS_I(*pinode)->uniqueid;
597 inode->i_mode |= S_IFDIR;
598 else
599 inode->i_mode |= S_IFREG;
600 } 525 }
601 526
602 cifsInfo->server_eof = le64_to_cpu(pfindData->EndOfFile); 527 /* query for SFU type info if supported and needed */
603 spin_lock(&inode->i_lock); 528 if (fattr.cf_cifsattrs & ATTR_SYSTEM &&
604 if (is_size_safe_to_change(cifsInfo, cifsInfo->server_eof)) { 529 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
605 /* can not safely shrink the file size here if the 530 tmprc = cifs_sfu_type(&fattr, full_path, cifs_sb, xid);
606 client is writing to it due to potential races */ 531 if (tmprc)
607 i_size_write(inode, cifsInfo->server_eof); 532 cFYI(1, ("cifs_sfu_type failed: %d", tmprc));
608
609 /* 512 bytes (2**9) is the fake blocksize that must be
610 used for this calculation */
611 inode->i_blocks = (512 - 1 + le64_to_cpu(
612 pfindData->AllocationSize)) >> 9;
613 } 533 }
614 spin_unlock(&inode->i_lock);
615 534
616 inode->i_nlink = le32_to_cpu(pfindData->NumberOfLinks);
617
618 /* BB fill in uid and gid here? with help from winbind?
619 or retrieve from NTFS stream extended attribute */
620#ifdef CONFIG_CIFS_EXPERIMENTAL 535#ifdef CONFIG_CIFS_EXPERIMENTAL
621 /* fill in 0777 bits from ACL */ 536 /* fill in 0777 bits from ACL */
622 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { 537 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) {
623 cFYI(1, ("Getting mode bits from ACL")); 538 cFYI(1, ("Getting mode bits from ACL"));
624 acl_to_uid_mode(cifs_sb, inode, full_path, pfid); 539 cifs_acl_to_fattr(cifs_sb, &fattr, *pinode, full_path, pfid);
625 } 540 }
626#endif 541#endif
627 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL) {
628 /* fill in remaining high mode bits e.g. SUID, VTX */
629 get_sfu_mode(inode, full_path, cifs_sb, xid);
630 } else if (atomic_read(&cifsInfo->inUse) == 0) {
631 inode->i_uid = cifs_sb->mnt_uid;
632 inode->i_gid = cifs_sb->mnt_gid;
633 /* set so we do not keep refreshing these fields with
634 bad data after user has changed them in memory */
635 atomic_set(&cifsInfo->inUse, 1);
636 }
637
638 cifs_set_ops(inode, is_dfs_referral);
639
640 542
543 /* fill in remaining high mode bits e.g. SUID, VTX */
544 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UNX_EMUL)
545 cifs_sfu_mode(&fattr, full_path, cifs_sb, xid);
641 546
547 if (!*pinode) {
548 *pinode = cifs_iget(sb, &fattr);
549 if (!*pinode)
550 rc = -ENOMEM;
551 } else {
552 cifs_fattr_to_inode(*pinode, &fattr);
553 }
642 554
643cgii_exit: 555cgii_exit:
644 kfree(buf); 556 kfree(buf);
@@ -753,21 +665,14 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
753 return ERR_PTR(-ENOMEM); 665 return ERR_PTR(-ENOMEM);
754 666
755 xid = GetXid(); 667 xid = GetXid();
756 if (cifs_sb->tcon->unix_ext) { 668 if (cifs_sb->tcon->unix_ext)
757 rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid); 669 rc = cifs_get_inode_info_unix(&inode, full_path, sb, xid);
758 if (!inode) 670 else
759 return ERR_PTR(-ENOMEM); 671 rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
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
767 rc = cifs_get_inode_info(&inode, full_path, NULL, inode->i_sb,
768 xid, NULL); 672 xid, NULL);
769 unlock_new_inode(inode); 673
770 } 674 if (!inode)
675 return ERR_PTR(-ENOMEM);
771 676
772 if (rc && cifs_sb->tcon->ipc) { 677 if (rc && cifs_sb->tcon->ipc) {
773 cFYI(1, ("ipc connection - fake read inode")); 678 cFYI(1, ("ipc connection - fake read inode"));