aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/CHANGES2
-rw-r--r--fs/cifs/cifsacl.c240
-rw-r--r--fs/cifs/cifspdu.h3
-rw-r--r--fs/cifs/cifsproto.h4
-rw-r--r--fs/cifs/cifssmb.c65
-rw-r--r--fs/cifs/inode.c14
6 files changed, 315 insertions, 13 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 0c778765bd79..edd248367b36 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -5,6 +5,8 @@ Enable experimental Kerberos support. Return writebehind errors on flush
5and sync so that events like out of disk space get reported properly on 5and sync so that events like out of disk space get reported properly on
6cached files. Fix setxattr failure to certain Samba versions. Fix mount 6cached files. Fix setxattr failure to certain Samba versions. Fix mount
7of second share to disconnected server session (autoreconnect on this). 7of second share to disconnected server session (autoreconnect on this).
8Add ability to modify cifs acls for handling chmod (when mounted with
9cifsacl flag).
8 10
9Version 1.51 11Version 1.51
10------------ 12------------
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index c312adcba4fc..a7035bd18e4e 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -129,6 +129,54 @@ int compare_sids(const struct cifs_sid *ctsid, const struct cifs_sid *cwsid)
129 return (1); /* sids compare/match */ 129 return (1); /* sids compare/match */
130} 130}
131 131
132
133/* copy ntsd, owner sid, and group sid from a security descriptor to another */
134static void copy_sec_desc(const struct cifs_ntsd *pntsd,
135 struct cifs_ntsd *pnntsd, __u32 sidsoffset)
136{
137 int i;
138
139 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
140 struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
141
142 /* copy security descriptor control portion */
143 pnntsd->revision = pntsd->revision;
144 pnntsd->type = pntsd->type;
145 pnntsd->dacloffset = cpu_to_le32(sizeof(struct cifs_ntsd));
146 pnntsd->sacloffset = 0;
147 pnntsd->osidoffset = cpu_to_le32(sidsoffset);
148 pnntsd->gsidoffset = cpu_to_le32(sidsoffset + sizeof(struct cifs_sid));
149
150 /* copy owner sid */
151 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
152 le32_to_cpu(pntsd->osidoffset));
153 nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset);
154
155 nowner_sid_ptr->revision = owner_sid_ptr->revision;
156 nowner_sid_ptr->num_subauth = owner_sid_ptr->num_subauth;
157 for (i = 0; i < 6; i++)
158 nowner_sid_ptr->authority[i] = owner_sid_ptr->authority[i];
159 for (i = 0; i < 5; i++)
160 nowner_sid_ptr->sub_auth[i] = owner_sid_ptr->sub_auth[i];
161
162 /* copy group sid */
163 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
164 le32_to_cpu(pntsd->gsidoffset));
165 ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + sidsoffset +
166 sizeof(struct cifs_sid));
167
168 ngroup_sid_ptr->revision = group_sid_ptr->revision;
169 ngroup_sid_ptr->num_subauth = group_sid_ptr->num_subauth;
170 for (i = 0; i < 6; i++)
171 ngroup_sid_ptr->authority[i] = group_sid_ptr->authority[i];
172 for (i = 0; i < 5; i++)
173 ngroup_sid_ptr->sub_auth[i] =
174 cpu_to_le32(group_sid_ptr->sub_auth[i]);
175
176 return;
177}
178
179
132/* 180/*
133 change posix mode to reflect permissions 181 change posix mode to reflect permissions
134 pmode is the existing mode (we only want to overwrite part of this 182 pmode is the existing mode (we only want to overwrite part of this
@@ -220,6 +268,33 @@ static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
220 return; 268 return;
221} 269}
222 270
271static __le16 fill_ace_for_sid(struct cifs_ace *pntace,
272 const struct cifs_sid *psid, __u64 nmode, umode_t bits)
273{
274 int i;
275 __u16 size = 0;
276 __u32 access_req = 0;
277
278 pntace->type = ACCESS_ALLOWED;
279 pntace->flags = 0x0;
280 mode_to_access_flags(nmode, bits, &access_req);
281 if (!access_req)
282 access_req = SET_MINIMUM_RIGHTS;
283 pntace->access_req = cpu_to_le32(access_req);
284
285 pntace->sid.revision = psid->revision;
286 pntace->sid.num_subauth = psid->num_subauth;
287 for (i = 0; i < 6; i++)
288 pntace->sid.authority[i] = psid->authority[i];
289 for (i = 0; i < psid->num_subauth; i++)
290 pntace->sid.sub_auth[i] = psid->sub_auth[i];
291
292 size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth * 4);
293 pntace->size = cpu_to_le16(size);
294
295 return (size);
296}
297
223 298
224#ifdef CONFIG_CIFS_DEBUG2 299#ifdef CONFIG_CIFS_DEBUG2
225static void dump_ace(struct cifs_ace *pace, char *end_of_acl) 300static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
@@ -243,7 +318,7 @@ static void dump_ace(struct cifs_ace *pace, char *end_of_acl)
243 int i; 318 int i;
244 cFYI(1, ("ACE revision %d num_auth %d type %d flags %d size %d", 319 cFYI(1, ("ACE revision %d num_auth %d type %d flags %d size %d",
245 pace->sid.revision, pace->sid.num_subauth, pace->type, 320 pace->sid.revision, pace->sid.num_subauth, pace->type,
246 pace->flags, pace->size)); 321 pace->flags, le16_to_cpu(pace->size)));
247 for (i = 0; i < num_subauth; ++i) { 322 for (i = 0; i < num_subauth; ++i) {
248 cFYI(1, ("ACE sub_auth[%d]: 0x%x", i, 323 cFYI(1, ("ACE sub_auth[%d]: 0x%x", i,
249 le32_to_cpu(pace->sid.sub_auth[i]))); 324 le32_to_cpu(pace->sid.sub_auth[i])));
@@ -346,6 +421,28 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
346} 421}
347 422
348 423
424static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
425 struct cifs_sid *pgrpsid, __u64 nmode)
426{
427 __le16 size = 0;
428 struct cifs_acl *pnndacl;
429
430 pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl));
431
432 size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size),
433 pownersid, nmode, S_IRWXU);
434 size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
435 pgrpsid, nmode, S_IRWXG);
436 size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size),
437 &sid_everyone, nmode, S_IRWXO);
438
439 pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl));
440 pndacl->num_aces = 3;
441
442 return (0);
443}
444
445
349static int parse_sid(struct cifs_sid *psid, char *end_of_acl) 446static int parse_sid(struct cifs_sid *psid, char *end_of_acl)
350{ 447{
351 /* BB need to add parm so we can store the SID BB */ 448 /* BB need to add parm so we can store the SID BB */
@@ -432,6 +529,46 @@ static int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len,
432} 529}
433 530
434 531
532/* Convert permission bits from mode to equivalent CIFS ACL */
533static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
534 int acl_len, struct inode *inode, __u64 nmode)
535{
536 int rc = 0;
537 __u32 dacloffset;
538 __u32 ndacloffset;
539 __u32 sidsoffset;
540 struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
541 struct cifs_acl *dacl_ptr = NULL; /* no need for SACL ptr */
542 struct cifs_acl *ndacl_ptr = NULL; /* no need for SACL ptr */
543
544 if ((inode == NULL) || (pntsd == NULL) || (pnntsd == NULL))
545 return (-EIO);
546
547 owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
548 le32_to_cpu(pntsd->osidoffset));
549 group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
550 le32_to_cpu(pntsd->gsidoffset));
551
552 dacloffset = le32_to_cpu(pntsd->dacloffset);
553 dacl_ptr = (struct cifs_acl *)((char *)pntsd + dacloffset);
554
555 ndacloffset = sizeof(struct cifs_ntsd);
556 ndacl_ptr = (struct cifs_acl *)((char *)pnntsd + ndacloffset);
557 ndacl_ptr->revision = dacl_ptr->revision;
558 ndacl_ptr->size = 0;
559 ndacl_ptr->num_aces = 0;
560
561 rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr, nmode);
562
563 sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
564
565 /* copy security descriptor control portion and owner and group sid */
566 copy_sec_desc(pntsd, pnntsd, sidsoffset);
567
568 return (rc);
569}
570
571
435/* Retrieve an ACL from the server */ 572/* Retrieve an ACL from the server */
436static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode, 573static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode,
437 const char *path) 574 const char *path)
@@ -487,6 +624,64 @@ static struct cifs_ntsd *get_cifs_acl(u32 *pacllen, struct inode *inode,
487 return pntsd; 624 return pntsd;
488} 625}
489 626
627/* Set an ACL on the server */
628static int set_cifs_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
629 struct inode *inode, const char *path)
630{
631 struct cifsFileInfo *open_file;
632 int unlock_file = FALSE;
633 int xid;
634 int rc = -EIO;
635 __u16 fid;
636 struct super_block *sb;
637 struct cifs_sb_info *cifs_sb;
638
639#ifdef CONFIG_CIFS_DEBUG2
640 cFYI(1, ("set ACL for %s from mode 0x%x", path, inode->i_mode));
641#endif
642
643 if (!inode)
644 return (rc);
645
646 sb = inode->i_sb;
647 if (sb == NULL)
648 return (rc);
649
650 cifs_sb = CIFS_SB(sb);
651 xid = GetXid();
652
653 open_file = find_readable_file(CIFS_I(inode));
654 if (open_file) {
655 unlock_file = TRUE;
656 fid = open_file->netfid;
657 } else {
658 int oplock = FALSE;
659 /* open file */
660 rc = CIFSSMBOpen(xid, cifs_sb->tcon, path, FILE_OPEN,
661 WRITE_DAC, 0, &fid, &oplock, NULL,
662 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
663 CIFS_MOUNT_MAP_SPECIAL_CHR);
664 if (rc != 0) {
665 cERROR(1, ("Unable to open file to set ACL"));
666 FreeXid(xid);
667 return (rc);
668 }
669 }
670
671 rc = CIFSSMBSetCIFSACL(xid, cifs_sb->tcon, fid, pnntsd, acllen);
672#ifdef CONFIG_CIFS_DEBUG2
673 cFYI(1, ("SetCIFSACL rc = %d", rc));
674#endif
675 if (unlock_file == TRUE)
676 atomic_dec(&open_file->wrtPending);
677 else
678 CIFSSMBClose(xid, cifs_sb->tcon, fid);
679
680 FreeXid(xid);
681
682 return (rc);
683}
684
490/* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */ 685/* Translate the CIFS ACL (simlar to NTFS ACL) for a file into mode bits */
491void acl_to_uid_mode(struct inode *inode, const char *path) 686void acl_to_uid_mode(struct inode *inode, const char *path)
492{ 687{
@@ -510,24 +705,53 @@ void acl_to_uid_mode(struct inode *inode, const char *path)
510} 705}
511 706
512/* Convert mode bits to an ACL so we can update the ACL on the server */ 707/* Convert mode bits to an ACL so we can update the ACL on the server */
513int mode_to_acl(struct inode *inode, const char *path) 708int mode_to_acl(struct inode *inode, const char *path, __u64 nmode)
514{ 709{
515 int rc = 0; 710 int rc = 0;
516 __u32 acllen = 0; 711 __u32 acllen = 0;
517 struct cifs_ntsd *pntsd = NULL; 712 struct cifs_ntsd *pntsd = NULL; /* acl obtained from server */
713 struct cifs_ntsd *pnntsd = NULL; /* modified acl to be sent to server */
518 714
715#ifdef CONFIG_CIFS_DEBUG2
519 cFYI(1, ("set ACL from mode for %s", path)); 716 cFYI(1, ("set ACL from mode for %s", path));
717#endif
520 718
521 /* Get the security descriptor */ 719 /* Get the security descriptor */
522 pntsd = get_cifs_acl(&acllen, inode, path); 720 pntsd = get_cifs_acl(&acllen, inode, path);
523 721
524 /* Add/Modify the three ACEs for owner, group, everyone 722 /* Add three ACEs for owner, group, everyone getting rid of
525 while retaining the other ACEs */ 723 other ACEs as chmod disables ACEs and set the security descriptor */
526 724
527 /* Set the security descriptor */ 725 if (pntsd) {
726 /* allocate memory for the smb header,
727 set security descriptor request security descriptor
728 parameters, and secuirty descriptor itself */
528 729
730 pnntsd = kmalloc(acllen, GFP_KERNEL);
731 if (!pnntsd) {
732 cERROR(1, ("Unable to allocate security descriptor"));
733 kfree(pntsd);
734 return (-ENOMEM);
735 }
529 736
530 kfree(pntsd); 737 rc = build_sec_desc(pntsd, pnntsd, acllen, inode, nmode);
531 return rc; 738
739#ifdef CONFIG_CIFS_DEBUG2
740 cFYI(1, ("build_sec_desc rc: %d", rc));
741#endif
742
743 if (!rc) {
744 /* Set the security descriptor */
745 rc = set_cifs_acl(pnntsd, acllen, inode, path);
746#ifdef CONFIG_CIFS_DEBUG2
747 cFYI(1, ("set_cifs_acl rc: %d", rc));
748#endif
749 }
750
751 kfree(pnntsd);
752 kfree(pntsd);
753 }
754
755 return (rc);
532} 756}
533#endif /* CONFIG_CIFS_EXPERIMENTAL */ 757#endif /* CONFIG_CIFS_EXPERIMENTAL */
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index dbe6b846f37f..47f79504f57b 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -237,6 +237,9 @@
237 | DELETE | READ_CONTROL | WRITE_DAC \ 237 | DELETE | READ_CONTROL | WRITE_DAC \
238 | WRITE_OWNER | SYNCHRONIZE) 238 | WRITE_OWNER | SYNCHRONIZE)
239 239
240#define SET_MINIMUM_RIGHTS (FILE_READ_EA | FILE_READ_ATTRIBUTES \
241 | READ_CONTROL | SYNCHRONIZE)
242
240 243
241/* 244/*
242 * Invalid readdir handle 245 * Invalid readdir handle
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 8350eec49663..7093cb4b0212 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -97,7 +97,7 @@ extern int cifs_get_inode_info_unix(struct inode **pinode,
97 const unsigned char *search_path, 97 const unsigned char *search_path,
98 struct super_block *sb, int xid); 98 struct super_block *sb, int xid);
99extern void acl_to_uid_mode(struct inode *inode, const char *search_path); 99extern void acl_to_uid_mode(struct inode *inode, const char *search_path);
100extern int mode_to_acl(struct inode *inode, const char *path); 100extern int mode_to_acl(struct inode *inode, const char *path, __u64);
101 101
102extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *, 102extern int cifs_mount(struct super_block *, struct cifs_sb_info *, char *,
103 const char *); 103 const char *);
@@ -342,6 +342,8 @@ extern int CIFSSMBSetEA(const int xid, struct cifsTconInfo *tcon,
342 const struct nls_table *nls_codepage, int remap_special_chars); 342 const struct nls_table *nls_codepage, int remap_special_chars);
343extern int CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, 343extern int CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon,
344 __u16 fid, struct cifs_ntsd **acl_inf, __u32 *buflen); 344 __u16 fid, struct cifs_ntsd **acl_inf, __u32 *buflen);
345extern int CIFSSMBSetCIFSACL(const int, struct cifsTconInfo *, __u16,
346 struct cifs_ntsd *, __u32);
345extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon, 347extern int CIFSSMBGetPosixACL(const int xid, struct cifsTconInfo *tcon,
346 const unsigned char *searchName, 348 const unsigned char *searchName,
347 char *acl_inf, const int buflen, const int acl_type, 349 char *acl_inf, const int buflen, const int acl_type,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 618542b8ce0b..9409524e4bf8 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -3156,6 +3156,71 @@ qsec_out:
3156/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ 3156/* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */
3157 return rc; 3157 return rc;
3158} 3158}
3159
3160int
3161CIFSSMBSetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid,
3162 struct cifs_ntsd *pntsd, __u32 acllen)
3163{
3164 __u16 byte_count, param_count, data_count, param_offset, data_offset;
3165 int rc = 0;
3166 int bytes_returned = 0;
3167 SET_SEC_DESC_REQ *pSMB = NULL;
3168 NTRANSACT_RSP *pSMBr = NULL;
3169
3170setCifsAclRetry:
3171 rc = smb_init(SMB_COM_NT_TRANSACT, 19, tcon, (void **) &pSMB,
3172 (void **) &pSMBr);
3173 if (rc)
3174 return (rc);
3175
3176 pSMB->MaxSetupCount = 0;
3177 pSMB->Reserved = 0;
3178
3179 param_count = 8;
3180 param_offset = offsetof(struct smb_com_transaction_ssec_req, Fid) - 4;
3181 data_count = acllen;
3182 data_offset = param_offset + param_count;
3183 byte_count = 3 /* pad */ + param_count;
3184
3185 pSMB->DataCount = cpu_to_le32(data_count);
3186 pSMB->TotalDataCount = pSMB->DataCount;
3187 pSMB->MaxParameterCount = cpu_to_le32(4);
3188 pSMB->MaxDataCount = cpu_to_le32(16384);
3189 pSMB->ParameterCount = cpu_to_le32(param_count);
3190 pSMB->ParameterOffset = cpu_to_le32(param_offset);
3191 pSMB->TotalParameterCount = pSMB->ParameterCount;
3192 pSMB->DataOffset = cpu_to_le32(data_offset);
3193 pSMB->SetupCount = 0;
3194 pSMB->SubCommand = cpu_to_le16(NT_TRANSACT_SET_SECURITY_DESC);
3195 pSMB->ByteCount = cpu_to_le16(byte_count+data_count);
3196
3197 pSMB->Fid = fid; /* file handle always le */
3198 pSMB->Reserved2 = 0;
3199 pSMB->AclFlags = cpu_to_le32(CIFS_ACL_DACL);
3200
3201 if (pntsd && acllen) {
3202 memcpy((char *) &pSMBr->hdr.Protocol + data_offset,
3203 (char *) pntsd,
3204 acllen);
3205 pSMB->hdr.smb_buf_length += (byte_count + data_count);
3206
3207 } else
3208 pSMB->hdr.smb_buf_length += byte_count;
3209
3210 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
3211 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
3212
3213 cFYI(1, ("SetCIFSACL bytes_returned: %d, rc: %d", bytes_returned, rc));
3214 if (rc)
3215 cFYI(1, ("Set CIFS ACL returned %d", rc));
3216 cifs_buf_release(pSMB);
3217
3218 if (rc == -EAGAIN)
3219 goto setCifsAclRetry;
3220
3221 return (rc);
3222}
3223
3159#endif /* CONFIG_CIFS_EXPERIMENTAL */ 3224#endif /* CONFIG_CIFS_EXPERIMENTAL */
3160 3225
3161/* Legacy Query Path Information call for lookup to old servers such 3226/* Legacy Query Path Information call for lookup to old servers such
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index e915eb1d2e66..fdc0fe109d7b 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -1607,7 +1607,13 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1607 CIFS_MOUNT_MAP_SPECIAL_CHR); 1607 CIFS_MOUNT_MAP_SPECIAL_CHR);
1608 else if (attrs->ia_valid & ATTR_MODE) { 1608 else if (attrs->ia_valid & ATTR_MODE) {
1609 rc = 0; 1609 rc = 0;
1610#ifdef CONFIG_CIFS_EXPERIMENTAL
1611 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
1612 rc = mode_to_acl(direntry->d_inode, full_path, mode);
1613 else if ((mode & S_IWUGO) == 0) /* not writeable */ {
1614#else
1610 if ((mode & S_IWUGO) == 0) /* not writeable */ { 1615 if ((mode & S_IWUGO) == 0) /* not writeable */ {
1616#endif
1611 if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) { 1617 if ((cifsInode->cifsAttrs & ATTR_READONLY) == 0) {
1612 set_dosattr = TRUE; 1618 set_dosattr = TRUE;
1613 time_buf.Attributes = 1619 time_buf.Attributes =
@@ -1626,10 +1632,10 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
1626 if (time_buf.Attributes == 0) 1632 if (time_buf.Attributes == 0)
1627 time_buf.Attributes |= cpu_to_le32(ATTR_NORMAL); 1633 time_buf.Attributes |= cpu_to_le32(ATTR_NORMAL);
1628 } 1634 }
1629 /* BB to be implemented - 1635#ifdef CONFIG_CIFS_EXPERIMENTAL
1630 via Windows security descriptors or streams */ 1636 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL)
1631 /* CIFSSMBWinSetPerms(xid, pTcon, full_path, mode, uid, gid, 1637 mode_to_acl(direntry->d_inode, full_path, mode);
1632 cifs_sb->local_nls); */ 1638#endif
1633 } 1639 }
1634 1640
1635 if (attrs->ia_valid & ATTR_ATIME) { 1641 if (attrs->ia_valid & ATTR_ATIME) {