aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/cifs/cifs_fs_sb.h4
-rw-r--r--fs/cifs/cifsacl.c18
-rw-r--r--fs/cifs/cifsglob.h7
-rw-r--r--fs/cifs/cifsproto.h1
-rw-r--r--fs/cifs/connect.c27
-rw-r--r--fs/cifs/dir.c10
-rw-r--r--fs/cifs/file.c12
-rw-r--r--fs/cifs/link.c17
-rw-r--r--fs/cifs/misc.c15
9 files changed, 95 insertions, 16 deletions
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 7260e11e21f8..500d65859279 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -43,6 +43,8 @@
43#define CIFS_MOUNT_STRICT_IO 0x40000 /* strict cache mode */ 43#define CIFS_MOUNT_STRICT_IO 0x40000 /* strict cache mode */
44#define CIFS_MOUNT_RWPIDFORWARD 0x80000 /* use pid forwarding for rw */ 44#define CIFS_MOUNT_RWPIDFORWARD 0x80000 /* use pid forwarding for rw */
45#define CIFS_MOUNT_POSIXACL 0x100000 /* mirror of MS_POSIXACL in mnt_cifs_flags */ 45#define CIFS_MOUNT_POSIXACL 0x100000 /* mirror of MS_POSIXACL in mnt_cifs_flags */
46#define CIFS_MOUNT_CIFS_BACKUPUID 0x200000 /* backup intent bit for a user */
47#define CIFS_MOUNT_CIFS_BACKUPGID 0x400000 /* backup intent bit for a group */
46 48
47struct cifs_sb_info { 49struct cifs_sb_info {
48 struct rb_root tlink_tree; 50 struct rb_root tlink_tree;
@@ -55,6 +57,8 @@ struct cifs_sb_info {
55 atomic_t active; 57 atomic_t active;
56 uid_t mnt_uid; 58 uid_t mnt_uid;
57 gid_t mnt_gid; 59 gid_t mnt_gid;
60 uid_t mnt_backupuid;
61 gid_t mnt_backupgid;
58 mode_t mnt_file_mode; 62 mode_t mnt_file_mode;
59 mode_t mnt_dir_mode; 63 mode_t mnt_dir_mode;
60 unsigned int mnt_cifs_flags; 64 unsigned int mnt_cifs_flags;
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index d0f59faefb78..b244e07c3048 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -945,7 +945,7 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
945{ 945{
946 struct cifs_ntsd *pntsd = NULL; 946 struct cifs_ntsd *pntsd = NULL;
947 int oplock = 0; 947 int oplock = 0;
948 int xid, rc; 948 int xid, rc, create_options = 0;
949 __u16 fid; 949 __u16 fid;
950 struct cifs_tcon *tcon; 950 struct cifs_tcon *tcon;
951 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); 951 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
@@ -956,9 +956,12 @@ static struct cifs_ntsd *get_cifs_acl_by_path(struct cifs_sb_info *cifs_sb,
956 tcon = tlink_tcon(tlink); 956 tcon = tlink_tcon(tlink);
957 xid = GetXid(); 957 xid = GetXid();
958 958
959 rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL, 0, 959 if (backup_cred(cifs_sb))
960 &fid, &oplock, NULL, cifs_sb->local_nls, 960 create_options |= CREATE_OPEN_BACKUP_INTENT;
961 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 961
962 rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, READ_CONTROL,
963 create_options, &fid, &oplock, NULL, cifs_sb->local_nls,
964 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
962 if (!rc) { 965 if (!rc) {
963 rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen); 966 rc = CIFSSMBGetCIFSACL(xid, tcon, fid, &pntsd, pacllen);
964 CIFSSMBClose(xid, tcon, fid); 967 CIFSSMBClose(xid, tcon, fid);
@@ -995,7 +998,7 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
995 struct cifs_ntsd *pnntsd, u32 acllen) 998 struct cifs_ntsd *pnntsd, u32 acllen)
996{ 999{
997 int oplock = 0; 1000 int oplock = 0;
998 int xid, rc; 1001 int xid, rc, create_options = 0;
999 __u16 fid; 1002 __u16 fid;
1000 struct cifs_tcon *tcon; 1003 struct cifs_tcon *tcon;
1001 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); 1004 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb);
@@ -1006,7 +1009,10 @@ static int set_cifs_acl_by_path(struct cifs_sb_info *cifs_sb, const char *path,
1006 tcon = tlink_tcon(tlink); 1009 tcon = tlink_tcon(tlink);
1007 xid = GetXid(); 1010 xid = GetXid();
1008 1011
1009 rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, WRITE_DAC, 0, 1012 if (backup_cred(cifs_sb))
1013 create_options |= CREATE_OPEN_BACKUP_INTENT;
1014
1015 rc = CIFSSMBOpen(xid, tcon, path, FILE_OPEN, WRITE_DAC, create_options,
1010 &fid, &oplock, NULL, cifs_sb->local_nls, 1016 &fid, &oplock, NULL, cifs_sb->local_nls,
1011 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 1017 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
1012 if (rc) { 1018 if (rc) {
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index d734dee9d495..9551437a2498 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -167,6 +167,8 @@ struct smb_vol {
167 uid_t cred_uid; 167 uid_t cred_uid;
168 uid_t linux_uid; 168 uid_t linux_uid;
169 gid_t linux_gid; 169 gid_t linux_gid;
170 uid_t backupuid;
171 gid_t backupgid;
170 mode_t file_mode; 172 mode_t file_mode;
171 mode_t dir_mode; 173 mode_t dir_mode;
172 unsigned secFlg; 174 unsigned secFlg;
@@ -179,6 +181,8 @@ struct smb_vol {
179 bool noperm:1; 181 bool noperm:1;
180 bool no_psx_acl:1; /* set if posix acl support should be disabled */ 182 bool no_psx_acl:1; /* set if posix acl support should be disabled */
181 bool cifs_acl:1; 183 bool cifs_acl:1;
184 bool backupuid_specified; /* mount option backupuid is specified */
185 bool backupgid_specified; /* mount option backupgid is specified */
182 bool no_xattr:1; /* set if xattr (EA) support should be disabled*/ 186 bool no_xattr:1; /* set if xattr (EA) support should be disabled*/
183 bool server_ino:1; /* use inode numbers from server ie UniqueId */ 187 bool server_ino:1; /* use inode numbers from server ie UniqueId */
184 bool direct_io:1; 188 bool direct_io:1;
@@ -219,7 +223,8 @@ struct smb_vol {
219 CIFS_MOUNT_OVERR_GID | CIFS_MOUNT_DYNPERM | \ 223 CIFS_MOUNT_OVERR_GID | CIFS_MOUNT_DYNPERM | \
220 CIFS_MOUNT_NOPOSIXBRL | CIFS_MOUNT_NOSSYNC | \ 224 CIFS_MOUNT_NOPOSIXBRL | CIFS_MOUNT_NOSSYNC | \
221 CIFS_MOUNT_FSCACHE | CIFS_MOUNT_MF_SYMLINKS | \ 225 CIFS_MOUNT_FSCACHE | CIFS_MOUNT_MF_SYMLINKS | \
222 CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO) 226 CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO | \
227 CIFS_MOUNT_CIFS_BACKUPUID | CIFS_MOUNT_CIFS_BACKUPGID)
223 228
224#define CIFS_MS_MASK (MS_RDONLY | MS_MANDLOCK | MS_NOEXEC | MS_NOSUID | \ 229#define CIFS_MS_MASK (MS_RDONLY | MS_MANDLOCK | MS_NOEXEC | MS_NOSUID | \
225 MS_NODEV | MS_SYNCHRONOUS) 230 MS_NODEV | MS_SYNCHRONOUS)
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 03dc945d94a3..9ddb1eccde69 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -90,6 +90,7 @@ extern int SendReceiveBlockingLock(const unsigned int xid,
90extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length); 90extern int checkSMB(struct smb_hdr *smb, __u16 mid, unsigned int length);
91extern bool is_valid_oplock_break(struct smb_hdr *smb, 91extern bool is_valid_oplock_break(struct smb_hdr *smb,
92 struct TCP_Server_Info *); 92 struct TCP_Server_Info *);
93extern bool backup_cred(struct cifs_sb_info *);
93extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof); 94extern bool is_size_safe_to_change(struct cifsInodeInfo *, __u64 eof);
94extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset, 95extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
95 unsigned int bytes_written); 96 unsigned int bytes_written);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index abbc6c3fe3f1..70dd2c418276 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -831,6 +831,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
831{ 831{
832 char *value, *data, *end; 832 char *value, *data, *end;
833 char *mountdata_copy = NULL, *options; 833 char *mountdata_copy = NULL, *options;
834 int err;
834 unsigned int temp_len, i, j; 835 unsigned int temp_len, i, j;
835 char separator[2]; 836 char separator[2];
836 short int override_uid = -1; 837 short int override_uid = -1;
@@ -887,6 +888,8 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
887 cFYI(1, "Null separator not allowed"); 888 cFYI(1, "Null separator not allowed");
888 } 889 }
889 } 890 }
891 vol->backupuid_specified = false; /* no backup intent for a user */
892 vol->backupgid_specified = false; /* no backup intent for a group */
890 893
891 while ((data = strsep(&options, separator)) != NULL) { 894 while ((data = strsep(&options, separator)) != NULL) {
892 if (!*data) 895 if (!*data)
@@ -1446,6 +1449,22 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1446 vol->mfsymlinks = true; 1449 vol->mfsymlinks = true;
1447 } else if (strnicmp(data, "multiuser", 8) == 0) { 1450 } else if (strnicmp(data, "multiuser", 8) == 0) {
1448 vol->multiuser = true; 1451 vol->multiuser = true;
1452 } else if (!strnicmp(data, "backupuid", 9) && value && *value) {
1453 err = kstrtouint(value, 0, &vol->backupuid);
1454 if (err < 0) {
1455 cERROR(1, "%s: Invalid backupuid value",
1456 __func__);
1457 goto cifs_parse_mount_err;
1458 }
1459 vol->backupuid_specified = true;
1460 } else if (!strnicmp(data, "backupgid", 9) && value && *value) {
1461 err = kstrtouint(value, 0, &vol->backupgid);
1462 if (err < 0) {
1463 cERROR(1, "%s: Invalid backupgid value",
1464 __func__);
1465 goto cifs_parse_mount_err;
1466 }
1467 vol->backupgid_specified = true;
1449 } else 1468 } else
1450 printk(KERN_WARNING "CIFS: Unknown mount option %s\n", 1469 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
1451 data); 1470 data);
@@ -2737,6 +2756,10 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
2737 2756
2738 cifs_sb->mnt_uid = pvolume_info->linux_uid; 2757 cifs_sb->mnt_uid = pvolume_info->linux_uid;
2739 cifs_sb->mnt_gid = pvolume_info->linux_gid; 2758 cifs_sb->mnt_gid = pvolume_info->linux_gid;
2759 if (pvolume_info->backupuid_specified)
2760 cifs_sb->mnt_backupuid = pvolume_info->backupuid;
2761 if (pvolume_info->backupgid_specified)
2762 cifs_sb->mnt_backupgid = pvolume_info->backupgid;
2740 cifs_sb->mnt_file_mode = pvolume_info->file_mode; 2763 cifs_sb->mnt_file_mode = pvolume_info->file_mode;
2741 cifs_sb->mnt_dir_mode = pvolume_info->dir_mode; 2764 cifs_sb->mnt_dir_mode = pvolume_info->dir_mode;
2742 cFYI(1, "file mode: 0x%x dir mode: 0x%x", 2765 cFYI(1, "file mode: 0x%x dir mode: 0x%x",
@@ -2767,6 +2790,10 @@ void cifs_setup_cifs_sb(struct smb_vol *pvolume_info,
2767 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD; 2790 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD;
2768 if (pvolume_info->cifs_acl) 2791 if (pvolume_info->cifs_acl)
2769 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL; 2792 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
2793 if (pvolume_info->backupuid_specified)
2794 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPUID;
2795 if (pvolume_info->backupgid_specified)
2796 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPGID;
2770 if (pvolume_info->override_uid) 2797 if (pvolume_info->override_uid)
2771 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID; 2798 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
2772 if (pvolume_info->override_gid) 2799 if (pvolume_info->override_gid)
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index 4dd5333753fa..0c8098d54d2b 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -244,6 +244,9 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
244 if (!tcon->unix_ext && (mode & S_IWUGO) == 0) 244 if (!tcon->unix_ext && (mode & S_IWUGO) == 0)
245 create_options |= CREATE_OPTION_READONLY; 245 create_options |= CREATE_OPTION_READONLY;
246 246
247 if (backup_cred(cifs_sb))
248 create_options |= CREATE_OPEN_BACKUP_INTENT;
249
247 if (tcon->ses->capabilities & CAP_NT_SMBS) 250 if (tcon->ses->capabilities & CAP_NT_SMBS)
248 rc = CIFSSMBOpen(xid, tcon, full_path, disposition, 251 rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
249 desiredAccess, create_options, 252 desiredAccess, create_options,
@@ -357,6 +360,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
357{ 360{
358 int rc = -EPERM; 361 int rc = -EPERM;
359 int xid; 362 int xid;
363 int create_options = CREATE_NOT_DIR | CREATE_OPTION_SPECIAL;
360 struct cifs_sb_info *cifs_sb; 364 struct cifs_sb_info *cifs_sb;
361 struct tcon_link *tlink; 365 struct tcon_link *tlink;
362 struct cifs_tcon *pTcon; 366 struct cifs_tcon *pTcon;
@@ -431,9 +435,11 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
431 return rc; 435 return rc;
432 } 436 }
433 437
434 /* FIXME: would WRITE_OWNER | WRITE_DAC be better? */ 438 if (backup_cred(cifs_sb))
439 create_options |= CREATE_OPEN_BACKUP_INTENT;
440
435 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_CREATE, 441 rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_CREATE,
436 GENERIC_WRITE, CREATE_NOT_DIR | CREATE_OPTION_SPECIAL, 442 GENERIC_WRITE, create_options,
437 &fileHandle, &oplock, buf, cifs_sb->local_nls, 443 &fileHandle, &oplock, buf, cifs_sb->local_nls,
438 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); 444 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
439 if (rc) 445 if (rc)
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 8e184150cfb5..237192ae7587 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -174,6 +174,7 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
174 int rc; 174 int rc;
175 int desiredAccess; 175 int desiredAccess;
176 int disposition; 176 int disposition;
177 int create_options = CREATE_NOT_DIR;
177 FILE_ALL_INFO *buf; 178 FILE_ALL_INFO *buf;
178 179
179 desiredAccess = cifs_convert_flags(f_flags); 180 desiredAccess = cifs_convert_flags(f_flags);
@@ -210,9 +211,12 @@ cifs_nt_open(char *full_path, struct inode *inode, struct cifs_sb_info *cifs_sb,
210 if (!buf) 211 if (!buf)
211 return -ENOMEM; 212 return -ENOMEM;
212 213
214 if (backup_cred(cifs_sb))
215 create_options |= CREATE_OPEN_BACKUP_INTENT;
216
213 if (tcon->ses->capabilities & CAP_NT_SMBS) 217 if (tcon->ses->capabilities & CAP_NT_SMBS)
214 rc = CIFSSMBOpen(xid, tcon, full_path, disposition, 218 rc = CIFSSMBOpen(xid, tcon, full_path, disposition,
215 desiredAccess, CREATE_NOT_DIR, pnetfid, poplock, buf, 219 desiredAccess, create_options, pnetfid, poplock, buf,
216 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags 220 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags
217 & CIFS_MOUNT_MAP_SPECIAL_CHR); 221 & CIFS_MOUNT_MAP_SPECIAL_CHR);
218 else 222 else
@@ -465,6 +469,7 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
465 char *full_path = NULL; 469 char *full_path = NULL;
466 int desiredAccess; 470 int desiredAccess;
467 int disposition = FILE_OPEN; 471 int disposition = FILE_OPEN;
472 int create_options = CREATE_NOT_DIR;
468 __u16 netfid; 473 __u16 netfid;
469 474
470 xid = GetXid(); 475 xid = GetXid();
@@ -524,6 +529,9 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
524 529
525 desiredAccess = cifs_convert_flags(pCifsFile->f_flags); 530 desiredAccess = cifs_convert_flags(pCifsFile->f_flags);
526 531
532 if (backup_cred(cifs_sb))
533 create_options |= CREATE_OPEN_BACKUP_INTENT;
534
527 /* Can not refresh inode by passing in file_info buf to be returned 535 /* Can not refresh inode by passing in file_info buf to be returned
528 by SMBOpen and then calling get_inode_info with returned buf 536 by SMBOpen and then calling get_inode_info with returned buf
529 since file might have write behind data that needs to be flushed 537 since file might have write behind data that needs to be flushed
@@ -531,7 +539,7 @@ static int cifs_reopen_file(struct cifsFileInfo *pCifsFile, bool can_flush)
531 that inode was not dirty locally we could do this */ 539 that inode was not dirty locally we could do this */
532 540
533 rc = CIFSSMBOpen(xid, tcon, full_path, disposition, desiredAccess, 541 rc = CIFSSMBOpen(xid, tcon, full_path, disposition, desiredAccess,
534 CREATE_NOT_DIR, &netfid, &oplock, NULL, 542 create_options, &netfid, &oplock, NULL,
535 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 543 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
536 CIFS_MOUNT_MAP_SPECIAL_CHR); 544 CIFS_MOUNT_MAP_SPECIAL_CHR);
537 if (rc) { 545 if (rc) {
diff --git a/fs/cifs/link.c b/fs/cifs/link.c
index db3f18cdf024..8693b5d0e180 100644
--- a/fs/cifs/link.c
+++ b/fs/cifs/link.c
@@ -183,14 +183,20 @@ CIFSFormatMFSymlink(u8 *buf, unsigned int buf_len, const char *link_str)
183static int 183static int
184CIFSCreateMFSymLink(const int xid, struct cifs_tcon *tcon, 184CIFSCreateMFSymLink(const int xid, struct cifs_tcon *tcon,
185 const char *fromName, const char *toName, 185 const char *fromName, const char *toName,
186 const struct nls_table *nls_codepage, int remap) 186 struct cifs_sb_info *cifs_sb)
187{ 187{
188 int rc; 188 int rc;
189 int oplock = 0; 189 int oplock = 0;
190 int remap;
191 int create_options = CREATE_NOT_DIR;
190 __u16 netfid = 0; 192 __u16 netfid = 0;
191 u8 *buf; 193 u8 *buf;
192 unsigned int bytes_written = 0; 194 unsigned int bytes_written = 0;
193 struct cifs_io_parms io_parms; 195 struct cifs_io_parms io_parms;
196 struct nls_table *nls_codepage;
197
198 nls_codepage = cifs_sb->local_nls;
199 remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR;
194 200
195 buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL); 201 buf = kmalloc(CIFS_MF_SYMLINK_FILE_SIZE, GFP_KERNEL);
196 if (!buf) 202 if (!buf)
@@ -202,8 +208,11 @@ CIFSCreateMFSymLink(const int xid, struct cifs_tcon *tcon,
202 return rc; 208 return rc;
203 } 209 }
204 210
211 if (backup_cred(cifs_sb))
212 create_options |= CREATE_OPEN_BACKUP_INTENT;
213
205 rc = CIFSSMBOpen(xid, tcon, fromName, FILE_CREATE, GENERIC_WRITE, 214 rc = CIFSSMBOpen(xid, tcon, fromName, FILE_CREATE, GENERIC_WRITE,
206 CREATE_NOT_DIR, &netfid, &oplock, NULL, 215 create_options, &netfid, &oplock, NULL,
207 nls_codepage, remap); 216 nls_codepage, remap);
208 if (rc != 0) { 217 if (rc != 0) {
209 kfree(buf); 218 kfree(buf);
@@ -559,9 +568,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
559 /* BB what if DFS and this volume is on different share? BB */ 568 /* BB what if DFS and this volume is on different share? BB */
560 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS) 569 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MF_SYMLINKS)
561 rc = CIFSCreateMFSymLink(xid, pTcon, full_path, symname, 570 rc = CIFSCreateMFSymLink(xid, pTcon, full_path, symname,
562 cifs_sb->local_nls, 571 cifs_sb);
563 cifs_sb->mnt_cifs_flags &
564 CIFS_MOUNT_MAP_SPECIAL_CHR);
565 else if (pTcon->unix_ext) 572 else if (pTcon->unix_ext)
566 rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname, 573 rc = CIFSUnixCreateSymLink(xid, pTcon, full_path, symname,
567 cifs_sb->local_nls); 574 cifs_sb->local_nls);
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 4a1801b3195f..703ef5c6fdb1 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -675,3 +675,18 @@ void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock)
675 cinode->clientCanCacheRead = false; 675 cinode->clientCanCacheRead = false;
676 } 676 }
677} 677}
678
679bool
680backup_cred(struct cifs_sb_info *cifs_sb)
681{
682 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID) {
683 if (cifs_sb->mnt_backupuid == current_fsuid())
684 return true;
685 }
686 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID) {
687 if (in_group_p(cifs_sb->mnt_backupgid))
688 return true;
689 }
690
691 return false;
692}