diff options
Diffstat (limited to 'fs')
79 files changed, 1493 insertions, 767 deletions
diff --git a/fs/Kconfig b/fs/Kconfig index e31f3691b151..cc28a69246a7 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -220,7 +220,7 @@ config JBD | |||
220 | 220 | ||
221 | config JBD_DEBUG | 221 | config JBD_DEBUG |
222 | bool "JBD (ext3) debugging support" | 222 | bool "JBD (ext3) debugging support" |
223 | depends on JBD | 223 | depends on JBD && DEBUG_FS |
224 | help | 224 | help |
225 | If you are using the ext3 journaled file system (or potentially any | 225 | If you are using the ext3 journaled file system (or potentially any |
226 | other file system/device using JBD), this option allows you to | 226 | other file system/device using JBD), this option allows you to |
@@ -229,10 +229,10 @@ config JBD_DEBUG | |||
229 | debugging output will be turned off. | 229 | debugging output will be turned off. |
230 | 230 | ||
231 | If you select Y here, then you will be able to turn on debugging | 231 | If you select Y here, then you will be able to turn on debugging |
232 | with "echo N > /proc/sys/fs/jbd-debug", where N is a number between | 232 | with "echo N > /sys/kernel/debug/jbd/jbd-debug", where N is a |
233 | 1 and 5, the higher the number, the more debugging output is | 233 | number between 1 and 5, the higher the number, the more debugging |
234 | generated. To turn debugging off again, do | 234 | output is generated. To turn debugging off again, do |
235 | "echo 0 > /proc/sys/fs/jbd-debug". | 235 | "echo 0 > /sys/kernel/debug/jbd/jbd-debug". |
236 | 236 | ||
237 | config JBD2 | 237 | config JBD2 |
238 | tristate | 238 | tristate |
diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c index e7204d71acc9..45f5992a0957 100644 --- a/fs/autofs/inode.c +++ b/fs/autofs/inode.c | |||
@@ -80,7 +80,7 @@ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, | |||
80 | 80 | ||
81 | *uid = current->uid; | 81 | *uid = current->uid; |
82 | *gid = current->gid; | 82 | *gid = current->gid; |
83 | *pgrp = process_group(current); | 83 | *pgrp = task_pgrp_nr(current); |
84 | 84 | ||
85 | *minproto = *maxproto = AUTOFS_PROTO_VERSION; | 85 | *minproto = *maxproto = AUTOFS_PROTO_VERSION; |
86 | 86 | ||
diff --git a/fs/autofs/root.c b/fs/autofs/root.c index c1489533277a..5efff3c0d886 100644 --- a/fs/autofs/root.c +++ b/fs/autofs/root.c | |||
@@ -214,8 +214,8 @@ static struct dentry *autofs_root_lookup(struct inode *dir, struct dentry *dentr | |||
214 | 214 | ||
215 | oz_mode = autofs_oz_mode(sbi); | 215 | oz_mode = autofs_oz_mode(sbi); |
216 | DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, " | 216 | DPRINTK(("autofs_lookup: pid = %u, pgrp = %u, catatonic = %d, " |
217 | "oz_mode = %d\n", pid_nr(task_pid(current)), | 217 | "oz_mode = %d\n", task_pid_nr(current), |
218 | process_group(current), sbi->catatonic, | 218 | task_pgrp_nr(current), sbi->catatonic, |
219 | oz_mode)); | 219 | oz_mode)); |
220 | 220 | ||
221 | /* | 221 | /* |
@@ -536,7 +536,7 @@ static int autofs_root_ioctl(struct inode *inode, struct file *filp, | |||
536 | struct autofs_sb_info *sbi = autofs_sbi(inode->i_sb); | 536 | struct autofs_sb_info *sbi = autofs_sbi(inode->i_sb); |
537 | void __user *argp = (void __user *)arg; | 537 | void __user *argp = (void __user *)arg; |
538 | 538 | ||
539 | DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",cmd,arg,sbi,process_group(current))); | 539 | DPRINTK(("autofs_ioctl: cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u\n",cmd,arg,sbi,task_pgrp_nr(current))); |
540 | 540 | ||
541 | if (_IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) || | 541 | if (_IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) || |
542 | _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT) | 542 | _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT) |
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h index d85f42fa9206..2d4ae40718d9 100644 --- a/fs/autofs4/autofs_i.h +++ b/fs/autofs4/autofs_i.h | |||
@@ -131,7 +131,7 @@ static inline struct autofs_info *autofs4_dentry_ino(struct dentry *dentry) | |||
131 | filesystem without "magic".) */ | 131 | filesystem without "magic".) */ |
132 | 132 | ||
133 | static inline int autofs4_oz_mode(struct autofs_sb_info *sbi) { | 133 | static inline int autofs4_oz_mode(struct autofs_sb_info *sbi) { |
134 | return sbi->catatonic || process_group(current) == sbi->oz_pgrp; | 134 | return sbi->catatonic || task_pgrp_nr(current) == sbi->oz_pgrp; |
135 | } | 135 | } |
136 | 136 | ||
137 | /* Does a dentry have some pending activity? */ | 137 | /* Does a dentry have some pending activity? */ |
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c index cd81f0836671..7f05d6ccdb13 100644 --- a/fs/autofs4/inode.c +++ b/fs/autofs4/inode.c | |||
@@ -226,7 +226,7 @@ static int parse_options(char *options, int *pipefd, uid_t *uid, gid_t *gid, | |||
226 | 226 | ||
227 | *uid = current->uid; | 227 | *uid = current->uid; |
228 | *gid = current->gid; | 228 | *gid = current->gid; |
229 | *pgrp = process_group(current); | 229 | *pgrp = task_pgrp_nr(current); |
230 | 230 | ||
231 | *minproto = AUTOFS_MIN_PROTO_VERSION; | 231 | *minproto = AUTOFS_MIN_PROTO_VERSION; |
232 | *maxproto = AUTOFS_MAX_PROTO_VERSION; | 232 | *maxproto = AUTOFS_MAX_PROTO_VERSION; |
@@ -323,7 +323,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) | |||
323 | sbi->pipe = NULL; | 323 | sbi->pipe = NULL; |
324 | sbi->catatonic = 1; | 324 | sbi->catatonic = 1; |
325 | sbi->exp_timeout = 0; | 325 | sbi->exp_timeout = 0; |
326 | sbi->oz_pgrp = process_group(current); | 326 | sbi->oz_pgrp = task_pgrp_nr(current); |
327 | sbi->sb = s; | 327 | sbi->sb = s; |
328 | sbi->version = 0; | 328 | sbi->version = 0; |
329 | sbi->sub_version = 0; | 329 | sbi->sub_version = 0; |
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 45ff3d63b758..2bbcc8151dc3 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
@@ -582,7 +582,7 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s | |||
582 | oz_mode = autofs4_oz_mode(sbi); | 582 | oz_mode = autofs4_oz_mode(sbi); |
583 | 583 | ||
584 | DPRINTK("pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d", | 584 | DPRINTK("pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d", |
585 | current->pid, process_group(current), sbi->catatonic, oz_mode); | 585 | current->pid, task_pgrp_nr(current), sbi->catatonic, oz_mode); |
586 | 586 | ||
587 | unhashed = autofs4_lookup_unhashed(sbi, dentry->d_parent, &dentry->d_name); | 587 | unhashed = autofs4_lookup_unhashed(sbi, dentry->d_parent, &dentry->d_name); |
588 | if (!unhashed) { | 588 | if (!unhashed) { |
@@ -976,7 +976,7 @@ static int autofs4_root_ioctl(struct inode *inode, struct file *filp, | |||
976 | void __user *p = (void __user *)arg; | 976 | void __user *p = (void __user *)arg; |
977 | 977 | ||
978 | DPRINTK("cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u", | 978 | DPRINTK("cmd = 0x%08x, arg = 0x%08lx, sbi = %p, pgrp = %u", |
979 | cmd,arg,sbi,process_group(current)); | 979 | cmd,arg,sbi,task_pgrp_nr(current)); |
980 | 980 | ||
981 | if (_IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) || | 981 | if (_IOC_TYPE(cmd) != _IOC_TYPE(AUTOFS_IOC_FIRST) || |
982 | _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT) | 982 | _IOC_NR(cmd) - _IOC_NR(AUTOFS_IOC_FIRST) >= AUTOFS_IOC_COUNT) |
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c index 6e2f3b8dde7f..ba8de7ca260b 100644 --- a/fs/binfmt_elf.c +++ b/fs/binfmt_elf.c | |||
@@ -1383,10 +1383,10 @@ static void fill_prstatus(struct elf_prstatus *prstatus, | |||
1383 | prstatus->pr_info.si_signo = prstatus->pr_cursig = signr; | 1383 | prstatus->pr_info.si_signo = prstatus->pr_cursig = signr; |
1384 | prstatus->pr_sigpend = p->pending.signal.sig[0]; | 1384 | prstatus->pr_sigpend = p->pending.signal.sig[0]; |
1385 | prstatus->pr_sighold = p->blocked.sig[0]; | 1385 | prstatus->pr_sighold = p->blocked.sig[0]; |
1386 | prstatus->pr_pid = p->pid; | 1386 | prstatus->pr_pid = task_pid_vnr(p); |
1387 | prstatus->pr_ppid = p->parent->pid; | 1387 | prstatus->pr_ppid = task_pid_vnr(p->parent); |
1388 | prstatus->pr_pgrp = process_group(p); | 1388 | prstatus->pr_pgrp = task_pgrp_vnr(p); |
1389 | prstatus->pr_sid = process_session(p); | 1389 | prstatus->pr_sid = task_session_vnr(p); |
1390 | if (thread_group_leader(p)) { | 1390 | if (thread_group_leader(p)) { |
1391 | /* | 1391 | /* |
1392 | * This is the record for the group leader. Add in the | 1392 | * This is the record for the group leader. Add in the |
@@ -1429,10 +1429,10 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, | |||
1429 | psinfo->pr_psargs[i] = ' '; | 1429 | psinfo->pr_psargs[i] = ' '; |
1430 | psinfo->pr_psargs[len] = 0; | 1430 | psinfo->pr_psargs[len] = 0; |
1431 | 1431 | ||
1432 | psinfo->pr_pid = p->pid; | 1432 | psinfo->pr_pid = task_pid_vnr(p); |
1433 | psinfo->pr_ppid = p->parent->pid; | 1433 | psinfo->pr_ppid = task_pid_vnr(p->parent); |
1434 | psinfo->pr_pgrp = process_group(p); | 1434 | psinfo->pr_pgrp = task_pgrp_vnr(p); |
1435 | psinfo->pr_sid = process_session(p); | 1435 | psinfo->pr_sid = task_session_vnr(p); |
1436 | 1436 | ||
1437 | i = p->state ? ffz(~p->state) + 1 : 0; | 1437 | i = p->state ? ffz(~p->state) + 1 : 0; |
1438 | psinfo->pr_state = i; | 1438 | psinfo->pr_state = i; |
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c index 033861c6b8f1..32649f2a1654 100644 --- a/fs/binfmt_elf_fdpic.c +++ b/fs/binfmt_elf_fdpic.c | |||
@@ -1342,10 +1342,10 @@ static void fill_prstatus(struct elf_prstatus *prstatus, | |||
1342 | prstatus->pr_info.si_signo = prstatus->pr_cursig = signr; | 1342 | prstatus->pr_info.si_signo = prstatus->pr_cursig = signr; |
1343 | prstatus->pr_sigpend = p->pending.signal.sig[0]; | 1343 | prstatus->pr_sigpend = p->pending.signal.sig[0]; |
1344 | prstatus->pr_sighold = p->blocked.sig[0]; | 1344 | prstatus->pr_sighold = p->blocked.sig[0]; |
1345 | prstatus->pr_pid = p->pid; | 1345 | prstatus->pr_pid = task_pid_vnr(p); |
1346 | prstatus->pr_ppid = p->parent->pid; | 1346 | prstatus->pr_ppid = task_pid_vnr(p->parent); |
1347 | prstatus->pr_pgrp = process_group(p); | 1347 | prstatus->pr_pgrp = task_pgrp_vnr(p); |
1348 | prstatus->pr_sid = process_session(p); | 1348 | prstatus->pr_sid = task_session_vnr(p); |
1349 | if (thread_group_leader(p)) { | 1349 | if (thread_group_leader(p)) { |
1350 | /* | 1350 | /* |
1351 | * This is the record for the group leader. Add in the | 1351 | * This is the record for the group leader. Add in the |
@@ -1391,10 +1391,10 @@ static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p, | |||
1391 | psinfo->pr_psargs[i] = ' '; | 1391 | psinfo->pr_psargs[i] = ' '; |
1392 | psinfo->pr_psargs[len] = 0; | 1392 | psinfo->pr_psargs[len] = 0; |
1393 | 1393 | ||
1394 | psinfo->pr_pid = p->pid; | 1394 | psinfo->pr_pid = task_pid_vnr(p); |
1395 | psinfo->pr_ppid = p->parent->pid; | 1395 | psinfo->pr_ppid = task_pid_vnr(p->parent); |
1396 | psinfo->pr_pgrp = process_group(p); | 1396 | psinfo->pr_pgrp = task_pgrp_vnr(p); |
1397 | psinfo->pr_sid = process_session(p); | 1397 | psinfo->pr_sid = task_session_vnr(p); |
1398 | 1398 | ||
1399 | i = p->state ? ffz(~p->state) + 1 : 0; | 1399 | i = p->state ? ffz(~p->state) + 1 : 0; |
1400 | psinfo->pr_state = i; | 1400 | psinfo->pr_state = i; |
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index bed6215c0794..3d419163c3d3 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
@@ -1,3 +1,19 @@ | |||
1 | Version 1.51 | ||
2 | ------------ | ||
3 | Fix memory leak in statfs when mounted to very old servers (e.g. | ||
4 | Windows 9x). Add new feature "POSIX open" which allows servers | ||
5 | which support the current POSIX Extensions to provide better semantics | ||
6 | (e.g. delete for open files opened with posix open). Take into | ||
7 | account umask on posix mkdir not just older style mkdir. Add | ||
8 | ability to mount to IPC$ share (which allows CIFS named pipes to be | ||
9 | opened, read and written as if they were files). When 1st tree | ||
10 | connect fails (e.g. due to signing negotiation failure) fix | ||
11 | leak that causes cifsd not to stop and rmmod to fail to cleanup | ||
12 | cifs_request_buffers pool. Fix problem with POSIX Open/Mkdir on | ||
13 | bigendian architectures. Fix possible memory corruption when | ||
14 | EAGAIN returned on kern_recvmsg. Return better error if server | ||
15 | requires packet signing but client has disabled it. | ||
16 | |||
1 | Version 1.50 | 17 | Version 1.50 |
2 | ------------ | 18 | ------------ |
3 | Fix NTLMv2 signing. NFS server mounted over cifs works (if cifs mount is | 19 | Fix NTLMv2 signing. NFS server mounted over cifs works (if cifs mount is |
@@ -6,7 +22,10 @@ done with "serverino" mount option). Add support for POSIX Unlink | |||
6 | Samba supports newer POSIX CIFS Protocol Extensions). Add "nounix" | 22 | Samba supports newer POSIX CIFS Protocol Extensions). Add "nounix" |
7 | mount option to allow disabling the CIFS Unix Extensions for just | 23 | mount option to allow disabling the CIFS Unix Extensions for just |
8 | that mount. Fix hang on spinlock in find_writable_file (race when | 24 | that mount. Fix hang on spinlock in find_writable_file (race when |
9 | reopening file after session crash). | 25 | reopening file after session crash). Byte range unlock request to |
26 | windows server could unlock more bytes (on server copy of file) | ||
27 | than intended if start of unlock request is well before start of | ||
28 | a previous byte range lock that we issued. | ||
10 | 29 | ||
11 | Version 1.49 | 30 | Version 1.49 |
12 | ------------ | 31 | ------------ |
diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile index 6ecd9d6ba3f3..ff6ba8d823f0 100644 --- a/fs/cifs/Makefile +++ b/fs/cifs/Makefile | |||
@@ -3,4 +3,4 @@ | |||
3 | # | 3 | # |
4 | obj-$(CONFIG_CIFS) += cifs.o | 4 | obj-$(CONFIG_CIFS) += cifs.o |
5 | 5 | ||
6 | cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o sess.o export.o | 6 | cifs-objs := cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o inode.o link.o misc.o netmisc.o smbdes.o smbencrypt.o transport.o asn1.o md4.o md5.o cifs_unicode.o nterr.o xattr.o cifsencrypt.o fcntl.o readdir.o ioctl.o sess.o export.o cifsacl.o |
diff --git a/fs/cifs/asn1.c b/fs/cifs/asn1.c index f50a88d58f78..2a01f3ef96a0 100644 --- a/fs/cifs/asn1.c +++ b/fs/cifs/asn1.c | |||
@@ -385,10 +385,9 @@ asn1_oid_decode(struct asn1_ctx *ctx, | |||
385 | unsigned long *optr; | 385 | unsigned long *optr; |
386 | 386 | ||
387 | size = eoc - ctx->pointer + 1; | 387 | size = eoc - ctx->pointer + 1; |
388 | *oid = kmalloc(size * sizeof (unsigned long), GFP_ATOMIC); | 388 | *oid = kmalloc(size * sizeof(unsigned long), GFP_ATOMIC); |
389 | if (*oid == NULL) { | 389 | if (*oid == NULL) |
390 | return 0; | 390 | return 0; |
391 | } | ||
392 | 391 | ||
393 | optr = *oid; | 392 | optr = *oid; |
394 | 393 | ||
@@ -581,9 +580,8 @@ decode_negTokenInit(unsigned char *security_blob, int length, | |||
581 | return 0; | 580 | return 0; |
582 | } else if ((cls != ASN1_UNI) || (con != ASN1_CON) | 581 | } else if ((cls != ASN1_UNI) || (con != ASN1_CON) |
583 | || (tag != ASN1_SEQ)) { | 582 | || (tag != ASN1_SEQ)) { |
584 | cFYI(1, | 583 | cFYI(1, ("cls = %d con = %d tag = %d end = %p (%d)", |
585 | ("Exit 6 cls = %d con = %d tag = %d end = %p (%d)", | 584 | cls, con, tag, end, *end)); |
586 | cls, con, tag, end, *end)); | ||
587 | } | 585 | } |
588 | 586 | ||
589 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { | 587 | if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) { |
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index 1bf8cf522ad6..73c4c419663c 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c | |||
@@ -209,13 +209,16 @@ cifs_debug_data_read(char *buf, char **beginBuffer, off_t offset, | |||
209 | i++; | 209 | i++; |
210 | tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); | 210 | tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); |
211 | dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType); | 211 | dev_type = le32_to_cpu(tcon->fsDevInfo.DeviceType); |
212 | length = | 212 | length = sprintf(buf, "\n%d) %s Uses: %d ", i, |
213 | sprintf(buf, | 213 | tcon->treeName, atomic_read(&tcon->useCount)); |
214 | "\n%d) %s Uses: %d Type: %s DevInfo: 0x%x " | 214 | buf += length; |
215 | "Attributes: 0x%x\nPathComponentMax: %d Status: %d", | 215 | if (tcon->nativeFileSystem) { |
216 | i, tcon->treeName, | 216 | length = sprintf(buf, "Type: %s ", |
217 | atomic_read(&tcon->useCount), | 217 | tcon->nativeFileSystem); |
218 | tcon->nativeFileSystem, | 218 | buf += length; |
219 | } | ||
220 | length = sprintf(buf, "DevInfo: 0x%x Attributes: 0x%x" | ||
221 | "\nPathComponentMax: %d Status: %d", | ||
219 | le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics), | 222 | le32_to_cpu(tcon->fsDevInfo.DeviceCharacteristics), |
220 | le32_to_cpu(tcon->fsAttrInfo.Attributes), | 223 | le32_to_cpu(tcon->fsAttrInfo.Attributes), |
221 | le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength), | 224 | le32_to_cpu(tcon->fsAttrInfo.MaxPathNameComponentLength), |
@@ -876,11 +879,16 @@ security_flags_write(struct file *file, const char __user *buffer, | |||
876 | if (count < 3) { | 879 | if (count < 3) { |
877 | /* single char or single char followed by null */ | 880 | /* single char or single char followed by null */ |
878 | c = flags_string[0]; | 881 | c = flags_string[0]; |
879 | if (c == '0' || c == 'n' || c == 'N') | 882 | if (c == '0' || c == 'n' || c == 'N') { |
880 | extended_security = CIFSSEC_DEF; /* default */ | 883 | extended_security = CIFSSEC_DEF; /* default */ |
881 | else if (c == '1' || c == 'y' || c == 'Y') | 884 | return count; |
885 | } else if (c == '1' || c == 'y' || c == 'Y') { | ||
882 | extended_security = CIFSSEC_MAX; | 886 | extended_security = CIFSSEC_MAX; |
883 | return count; | 887 | return count; |
888 | } else if (!isdigit(c)) { | ||
889 | cERROR(1, ("invalid flag %c", c)); | ||
890 | return -EINVAL; | ||
891 | } | ||
884 | } | 892 | } |
885 | /* else we have a number */ | 893 | /* else we have a number */ |
886 | 894 | ||
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c new file mode 100644 index 000000000000..e8e56353f5a1 --- /dev/null +++ b/fs/cifs/cifsacl.c | |||
@@ -0,0 +1,333 @@ | |||
1 | /* | ||
2 | * fs/cifs/cifsacl.c | ||
3 | * | ||
4 | * Copyright (C) International Business Machines Corp., 2007 | ||
5 | * Author(s): Steve French (sfrench@us.ibm.com) | ||
6 | * | ||
7 | * Contains the routines for mapping CIFS/NTFS ACLs | ||
8 | * | ||
9 | * This library is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU Lesser General Public License as published | ||
11 | * by the Free Software Foundation; either version 2.1 of the License, or | ||
12 | * (at your option) any later version. | ||
13 | * | ||
14 | * This library is distributed in the hope that it will be useful, | ||
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See | ||
17 | * the GNU Lesser General Public License for more details. | ||
18 | * | ||
19 | * You should have received a copy of the GNU Lesser General Public License | ||
20 | * along with this library; if not, write to the Free Software | ||
21 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | #include <linux/fs.h> | ||
25 | #include "cifspdu.h" | ||
26 | #include "cifsglob.h" | ||
27 | #include "cifsacl.h" | ||
28 | #include "cifsproto.h" | ||
29 | #include "cifs_debug.h" | ||
30 | |||
31 | |||
32 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
33 | |||
34 | static struct cifs_wksid wksidarr[NUM_WK_SIDS] = { | ||
35 | {{1, 0, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} }, "null user"}, | ||
36 | {{1, 1, {0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0} }, "nobody"}, | ||
37 | {{1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(11), 0, 0, 0, 0} }, "net-users"}, | ||
38 | {{1, 1, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(18), 0, 0, 0, 0} }, "sys"}, | ||
39 | {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(544), 0, 0, 0} }, "root"}, | ||
40 | {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(545), 0, 0, 0} }, "users"}, | ||
41 | {{1, 2, {0, 0, 0, 0, 0, 5}, {cpu_to_le32(32), cpu_to_le32(546), 0, 0, 0} }, "guest"} | ||
42 | }; | ||
43 | |||
44 | |||
45 | /* security id for everyone */ | ||
46 | static const struct cifs_sid sid_everyone = | ||
47 | {1, 1, {0, 0, 0, 0, 0, 0}, {} }; | ||
48 | /* group users */ | ||
49 | static const struct cifs_sid sid_user = | ||
50 | {1, 2 , {0, 0, 0, 0, 0, 5}, {} }; | ||
51 | |||
52 | |||
53 | int match_sid(struct cifs_sid *ctsid) | ||
54 | { | ||
55 | int i, j; | ||
56 | int num_subauth, num_sat, num_saw; | ||
57 | struct cifs_sid *cwsid; | ||
58 | |||
59 | if (!ctsid) | ||
60 | return (-1); | ||
61 | |||
62 | for (i = 0; i < NUM_WK_SIDS; ++i) { | ||
63 | cwsid = &(wksidarr[i].cifssid); | ||
64 | |||
65 | /* compare the revision */ | ||
66 | if (ctsid->revision != cwsid->revision) | ||
67 | continue; | ||
68 | |||
69 | /* compare all of the six auth values */ | ||
70 | for (j = 0; j < 6; ++j) { | ||
71 | if (ctsid->authority[j] != cwsid->authority[j]) | ||
72 | break; | ||
73 | } | ||
74 | if (j < 6) | ||
75 | continue; /* all of the auth values did not match */ | ||
76 | |||
77 | /* compare all of the subauth values if any */ | ||
78 | num_sat = ctsid->num_subauth; | ||
79 | num_saw = cwsid->num_subauth; | ||
80 | num_subauth = num_sat < num_saw ? num_sat : num_saw; | ||
81 | if (num_subauth) { | ||
82 | for (j = 0; j < num_subauth; ++j) { | ||
83 | if (ctsid->sub_auth[j] != cwsid->sub_auth[j]) | ||
84 | break; | ||
85 | } | ||
86 | if (j < num_subauth) | ||
87 | continue; /* all sub_auth values do not match */ | ||
88 | } | ||
89 | |||
90 | cFYI(1, ("matching sid: %s\n", wksidarr[i].sidname)); | ||
91 | return (0); /* sids compare/match */ | ||
92 | } | ||
93 | |||
94 | cFYI(1, ("No matching sid")); | ||
95 | return (-1); | ||
96 | } | ||
97 | |||
98 | /* if the two SIDs (roughly equivalent to a UUID for a user or group) are | ||
99 | the same returns 1, if they do not match returns 0 */ | ||
100 | int compare_sids(struct cifs_sid *ctsid, struct cifs_sid *cwsid) | ||
101 | { | ||
102 | int i; | ||
103 | int num_subauth, num_sat, num_saw; | ||
104 | |||
105 | if ((!ctsid) || (!cwsid)) | ||
106 | return (0); | ||
107 | |||
108 | /* compare the revision */ | ||
109 | if (ctsid->revision != cwsid->revision) | ||
110 | return (0); | ||
111 | |||
112 | /* compare all of the six auth values */ | ||
113 | for (i = 0; i < 6; ++i) { | ||
114 | if (ctsid->authority[i] != cwsid->authority[i]) | ||
115 | return (0); | ||
116 | } | ||
117 | |||
118 | /* compare all of the subauth values if any */ | ||
119 | num_sat = ctsid->num_subauth; | ||
120 | num_saw = cwsid->num_subauth; | ||
121 | num_subauth = num_sat < num_saw ? num_sat : num_saw; | ||
122 | if (num_subauth) { | ||
123 | for (i = 0; i < num_subauth; ++i) { | ||
124 | if (ctsid->sub_auth[i] != cwsid->sub_auth[i]) | ||
125 | return (0); | ||
126 | } | ||
127 | } | ||
128 | |||
129 | return (1); /* sids compare/match */ | ||
130 | } | ||
131 | |||
132 | |||
133 | static void parse_ace(struct cifs_ace *pace, char *end_of_acl) | ||
134 | { | ||
135 | int num_subauth; | ||
136 | |||
137 | /* validate that we do not go past end of acl */ | ||
138 | |||
139 | /* XXX this if statement can be removed | ||
140 | if (end_of_acl < (char *)pace + sizeof(struct cifs_ace)) { | ||
141 | cERROR(1, ("ACL too small to parse ACE")); | ||
142 | return; | ||
143 | } */ | ||
144 | |||
145 | num_subauth = pace->num_subauth; | ||
146 | if (num_subauth) { | ||
147 | #ifdef CONFIG_CIFS_DEBUG2 | ||
148 | int i; | ||
149 | cFYI(1, ("ACE revision %d num_subauth %d", | ||
150 | pace->revision, pace->num_subauth)); | ||
151 | for (i = 0; i < num_subauth; ++i) { | ||
152 | cFYI(1, ("ACE sub_auth[%d]: 0x%x", i, | ||
153 | le32_to_cpu(pace->sub_auth[i]))); | ||
154 | } | ||
155 | |||
156 | /* BB add length check to make sure that we do not have huge | ||
157 | num auths and therefore go off the end */ | ||
158 | |||
159 | cFYI(1, ("RID %d", le32_to_cpu(pace->sub_auth[num_subauth-1]))); | ||
160 | #endif | ||
161 | } | ||
162 | |||
163 | return; | ||
164 | } | ||
165 | |||
166 | static void parse_ntace(struct cifs_ntace *pntace, char *end_of_acl) | ||
167 | { | ||
168 | /* validate that we do not go past end of acl */ | ||
169 | if (end_of_acl < (char *)pntace + sizeof(struct cifs_ntace)) { | ||
170 | cERROR(1, ("ACL too small to parse NT ACE")); | ||
171 | return; | ||
172 | } | ||
173 | |||
174 | #ifdef CONFIG_CIFS_DEBUG2 | ||
175 | cFYI(1, ("NTACE type %d flags 0x%x size %d, access Req 0x%x", | ||
176 | pntace->type, pntace->flags, pntace->size, | ||
177 | pntace->access_req)); | ||
178 | #endif | ||
179 | return; | ||
180 | } | ||
181 | |||
182 | |||
183 | |||
184 | static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, | ||
185 | struct cifs_sid *pownersid, struct cifs_sid *pgrpsid) | ||
186 | { | ||
187 | int i; | ||
188 | int num_aces = 0; | ||
189 | int acl_size; | ||
190 | char *acl_base; | ||
191 | struct cifs_ntace **ppntace; | ||
192 | struct cifs_ace **ppace; | ||
193 | |||
194 | /* BB need to add parm so we can store the SID BB */ | ||
195 | |||
196 | /* validate that we do not go past end of acl */ | ||
197 | if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) { | ||
198 | cERROR(1, ("ACL too small to parse DACL")); | ||
199 | return; | ||
200 | } | ||
201 | |||
202 | #ifdef CONFIG_CIFS_DEBUG2 | ||
203 | cFYI(1, ("DACL revision %d size %d num aces %d", | ||
204 | le16_to_cpu(pdacl->revision), le16_to_cpu(pdacl->size), | ||
205 | le32_to_cpu(pdacl->num_aces))); | ||
206 | #endif | ||
207 | |||
208 | acl_base = (char *)pdacl; | ||
209 | acl_size = sizeof(struct cifs_acl); | ||
210 | |||
211 | num_aces = le32_to_cpu(pdacl->num_aces); | ||
212 | if (num_aces > 0) { | ||
213 | ppntace = kmalloc(num_aces * sizeof(struct cifs_ntace *), | ||
214 | GFP_KERNEL); | ||
215 | ppace = kmalloc(num_aces * sizeof(struct cifs_ace *), | ||
216 | GFP_KERNEL); | ||
217 | |||
218 | /* cifscred->cecount = pdacl->num_aces; | ||
219 | cifscred->ntaces = kmalloc(num_aces * | ||
220 | sizeof(struct cifs_ntace *), GFP_KERNEL); | ||
221 | cifscred->aces = kmalloc(num_aces * | ||
222 | sizeof(struct cifs_ace *), GFP_KERNEL);*/ | ||
223 | |||
224 | for (i = 0; i < num_aces; ++i) { | ||
225 | ppntace[i] = (struct cifs_ntace *) | ||
226 | (acl_base + acl_size); | ||
227 | ppace[i] = (struct cifs_ace *) ((char *)ppntace[i] + | ||
228 | sizeof(struct cifs_ntace)); | ||
229 | |||
230 | parse_ntace(ppntace[i], end_of_acl); | ||
231 | if (end_of_acl < ((char *)ppace[i] + | ||
232 | (le16_to_cpu(ppntace[i]->size) - | ||
233 | sizeof(struct cifs_ntace)))) { | ||
234 | cERROR(1, ("ACL too small to parse ACE")); | ||
235 | break; | ||
236 | } else | ||
237 | parse_ace(ppace[i], end_of_acl); | ||
238 | |||
239 | /* memcpy((void *)(&(cifscred->ntaces[i])), | ||
240 | (void *)ppntace[i], | ||
241 | sizeof(struct cifs_ntace)); | ||
242 | memcpy((void *)(&(cifscred->aces[i])), | ||
243 | (void *)ppace[i], | ||
244 | sizeof(struct cifs_ace)); */ | ||
245 | |||
246 | acl_base = (char *)ppntace[i]; | ||
247 | acl_size = le16_to_cpu(ppntace[i]->size); | ||
248 | } | ||
249 | |||
250 | kfree(ppace); | ||
251 | kfree(ppntace); | ||
252 | } | ||
253 | |||
254 | return; | ||
255 | } | ||
256 | |||
257 | |||
258 | static int parse_sid(struct cifs_sid *psid, char *end_of_acl) | ||
259 | { | ||
260 | |||
261 | /* BB need to add parm so we can store the SID BB */ | ||
262 | |||
263 | /* validate that we do not go past end of acl */ | ||
264 | if (end_of_acl < (char *)psid + sizeof(struct cifs_sid)) { | ||
265 | cERROR(1, ("ACL too small to parse SID")); | ||
266 | return -EINVAL; | ||
267 | } | ||
268 | |||
269 | if (psid->num_subauth) { | ||
270 | #ifdef CONFIG_CIFS_DEBUG2 | ||
271 | int i; | ||
272 | cFYI(1, ("SID revision %d num_auth %d First subauth 0x%x", | ||
273 | psid->revision, psid->num_subauth, psid->sub_auth[0])); | ||
274 | |||
275 | for (i = 0; i < psid->num_subauth; i++) { | ||
276 | cFYI(1, ("SID sub_auth[%d]: 0x%x ", i, | ||
277 | le32_to_cpu(psid->sub_auth[i]))); | ||
278 | } | ||
279 | |||
280 | /* BB add length check to make sure that we do not have huge | ||
281 | num auths and therefore go off the end */ | ||
282 | cFYI(1, ("RID 0x%x", | ||
283 | le32_to_cpu(psid->sub_auth[psid->num_subauth-1]))); | ||
284 | #endif | ||
285 | } | ||
286 | |||
287 | return 0; | ||
288 | } | ||
289 | |||
290 | |||
291 | /* Convert CIFS ACL to POSIX form */ | ||
292 | int parse_sec_desc(struct cifs_ntsd *pntsd, int acl_len) | ||
293 | { | ||
294 | int rc; | ||
295 | struct cifs_sid *owner_sid_ptr, *group_sid_ptr; | ||
296 | struct cifs_acl *dacl_ptr; /* no need for SACL ptr */ | ||
297 | char *end_of_acl = ((char *)pntsd) + acl_len; | ||
298 | |||
299 | owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + | ||
300 | le32_to_cpu(pntsd->osidoffset)); | ||
301 | group_sid_ptr = (struct cifs_sid *)((char *)pntsd + | ||
302 | le32_to_cpu(pntsd->gsidoffset)); | ||
303 | dacl_ptr = (struct cifs_acl *)((char *)pntsd + | ||
304 | le32_to_cpu(pntsd->dacloffset)); | ||
305 | #ifdef CONFIG_CIFS_DEBUG2 | ||
306 | cFYI(1, ("revision %d type 0x%x ooffset 0x%x goffset 0x%x " | ||
307 | "sacloffset 0x%x dacloffset 0x%x", | ||
308 | pntsd->revision, pntsd->type, le32_to_cpu(pntsd->osidoffset), | ||
309 | le32_to_cpu(pntsd->gsidoffset), | ||
310 | le32_to_cpu(pntsd->sacloffset), | ||
311 | le32_to_cpu(pntsd->dacloffset))); | ||
312 | #endif | ||
313 | rc = parse_sid(owner_sid_ptr, end_of_acl); | ||
314 | if (rc) | ||
315 | return rc; | ||
316 | |||
317 | rc = parse_sid(group_sid_ptr, end_of_acl); | ||
318 | if (rc) | ||
319 | return rc; | ||
320 | |||
321 | parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, group_sid_ptr); | ||
322 | |||
323 | /* cifscred->uid = owner_sid_ptr->rid; | ||
324 | cifscred->gid = group_sid_ptr->rid; | ||
325 | memcpy((void *)(&(cifscred->osid)), (void *)owner_sid_ptr, | ||
326 | sizeof (struct cifs_sid)); | ||
327 | memcpy((void *)(&(cifscred->gsid)), (void *)group_sid_ptr, | ||
328 | sizeof (struct cifs_sid)); */ | ||
329 | |||
330 | |||
331 | return (0); | ||
332 | } | ||
333 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | ||
diff --git a/fs/cifs/cifsacl.h b/fs/cifs/cifsacl.h index 5eff35d6e564..420f87813647 100644 --- a/fs/cifs/cifsacl.h +++ b/fs/cifs/cifsacl.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * fs/cifs/cifsacl.h | 2 | * fs/cifs/cifsacl.h |
3 | * | 3 | * |
4 | * Copyright (c) International Business Machines Corp., 2005 | 4 | * Copyright (c) International Business Machines Corp., 2007 |
5 | * Author(s): Steve French (sfrench@us.ibm.com) | 5 | * Author(s): Steve French (sfrench@us.ibm.com) |
6 | * | 6 | * |
7 | * This library is free software; you can redistribute it and/or modify | 7 | * This library is free software; you can redistribute it and/or modify |
@@ -22,17 +22,65 @@ | |||
22 | #ifndef _CIFSACL_H | 22 | #ifndef _CIFSACL_H |
23 | #define _CIFSACL_H | 23 | #define _CIFSACL_H |
24 | 24 | ||
25 | |||
26 | #define NUM_AUTHS 6 /* number of authority fields */ | ||
27 | #define NUM_SUBAUTHS 5 /* number of sub authority fields */ | ||
28 | #define NUM_WK_SIDS 7 /* number of well known sids */ | ||
29 | #define SIDNAMELENGTH 20 /* long enough for the ones we care about */ | ||
30 | |||
31 | #define READ_BIT 0x4 | ||
32 | #define WRITE_BIT 0x2 | ||
33 | #define EXEC_BIT 0x1 | ||
34 | |||
35 | #define UBITSHIFT 6 | ||
36 | #define GBITSHIFT 3 | ||
37 | |||
38 | struct cifs_ntsd { | ||
39 | __le16 revision; /* revision level */ | ||
40 | __le16 type; | ||
41 | __le32 osidoffset; | ||
42 | __le32 gsidoffset; | ||
43 | __le32 sacloffset; | ||
44 | __le32 dacloffset; | ||
45 | } __attribute__((packed)); | ||
46 | |||
25 | struct cifs_sid { | 47 | struct cifs_sid { |
26 | __u8 revision; /* revision level */ | 48 | __u8 revision; /* revision level */ |
27 | __u8 num_subauths; | 49 | __u8 num_subauth; |
50 | __u8 authority[6]; | ||
51 | __le32 sub_auth[5]; /* sub_auth[num_subauth] */ /* BB FIXME endianness BB */ | ||
52 | } __attribute__((packed)); | ||
53 | |||
54 | struct cifs_acl { | ||
55 | __le16 revision; /* revision level */ | ||
56 | __le16 size; | ||
57 | __le32 num_aces; | ||
58 | } __attribute__((packed)); | ||
59 | |||
60 | struct cifs_ntace { /* first part of ACE which contains perms */ | ||
61 | __u8 type; | ||
62 | __u8 flags; | ||
63 | __le16 size; | ||
64 | __le32 access_req; | ||
65 | } __attribute__((packed)); | ||
66 | |||
67 | struct cifs_ace { /* last part of ACE which includes user info */ | ||
68 | __u8 revision; /* revision level */ | ||
69 | __u8 num_subauth; | ||
28 | __u8 authority[6]; | 70 | __u8 authority[6]; |
29 | __u32 sub_auth[4]; | 71 | __le32 sub_auth[5]; |
30 | /* next sub_auth if any ... */ | ||
31 | } __attribute__((packed)); | 72 | } __attribute__((packed)); |
32 | 73 | ||
33 | /* everyone */ | 74 | struct cifs_wksid { |
34 | /* extern const struct cifs_sid sid_everyone;*/ | 75 | struct cifs_sid cifssid; |
35 | /* group users */ | 76 | char sidname[SIDNAMELENGTH]; |
36 | /* extern const struct cifs_sid sid_user;*/ | 77 | } __attribute__((packed)); |
78 | |||
79 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
80 | |||
81 | extern int match_sid(struct cifs_sid *); | ||
82 | extern int compare_sids(struct cifs_sid *, struct cifs_sid *); | ||
83 | |||
84 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | ||
37 | 85 | ||
38 | #endif /* _CIFSACL_H */ | 86 | #endif /* _CIFSACL_H */ |
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index 36272293027d..632070b4275d 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c | |||
@@ -345,7 +345,7 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses, | |||
345 | user = kmalloc(2 + (len * 2), GFP_KERNEL); | 345 | user = kmalloc(2 + (len * 2), GFP_KERNEL); |
346 | if (user == NULL) | 346 | if (user == NULL) |
347 | goto calc_exit_2; | 347 | goto calc_exit_2; |
348 | len = cifs_strtoUCS(user, ses->userName, len, nls_cp); | 348 | len = cifs_strtoUCS((__le16 *)user, ses->userName, len, nls_cp); |
349 | UniStrupr(user); | 349 | UniStrupr(user); |
350 | hmac_md5_update((char *)user, 2*len, pctxt); | 350 | hmac_md5_update((char *)user, 2*len, pctxt); |
351 | 351 | ||
@@ -356,7 +356,8 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses, | |||
356 | domain = kmalloc(2 + (len * 2), GFP_KERNEL); | 356 | domain = kmalloc(2 + (len * 2), GFP_KERNEL); |
357 | if (domain == NULL) | 357 | if (domain == NULL) |
358 | goto calc_exit_1; | 358 | goto calc_exit_1; |
359 | len = cifs_strtoUCS(domain, ses->domainName, len, nls_cp); | 359 | len = cifs_strtoUCS((__le16 *)domain, ses->domainName, len, |
360 | nls_cp); | ||
360 | /* the following line was removed since it didn't work well | 361 | /* the following line was removed since it didn't work well |
361 | with lower cased domain name that passed as an option. | 362 | with lower cased domain name that passed as an option. |
362 | Maybe converting the domain name earlier makes sense */ | 363 | Maybe converting the domain name earlier makes sense */ |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index ba8f7868cb23..a6fbea57c4b1 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -49,10 +49,6 @@ | |||
49 | static struct quotactl_ops cifs_quotactl_ops; | 49 | static struct quotactl_ops cifs_quotactl_ops; |
50 | #endif /* QUOTA */ | 50 | #endif /* QUOTA */ |
51 | 51 | ||
52 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
53 | extern struct export_operations cifs_export_ops; | ||
54 | #endif /* EXPERIMENTAL */ | ||
55 | |||
56 | int cifsFYI = 0; | 52 | int cifsFYI = 0; |
57 | int cifsERROR = 1; | 53 | int cifsERROR = 1; |
58 | int traceSMB = 0; | 54 | int traceSMB = 0; |
@@ -240,9 +236,9 @@ static int cifs_permission(struct inode *inode, int mask, struct nameidata *nd) | |||
240 | 236 | ||
241 | cifs_sb = CIFS_SB(inode->i_sb); | 237 | cifs_sb = CIFS_SB(inode->i_sb); |
242 | 238 | ||
243 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) { | 239 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_PERM) |
244 | return 0; | 240 | return 0; |
245 | } else /* file mode might have been restricted at mount time | 241 | else /* file mode might have been restricted at mount time |
246 | on the client (above and beyond ACL on servers) for | 242 | on the client (above and beyond ACL on servers) for |
247 | servers which do not support setting and viewing mode bits, | 243 | servers which do not support setting and viewing mode bits, |
248 | so allowing client to check permissions is useful */ | 244 | so allowing client to check permissions is useful */ |
@@ -312,15 +308,15 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m) | |||
312 | seq_printf(s, ",domain=%s", | 308 | seq_printf(s, ",domain=%s", |
313 | cifs_sb->tcon->ses->domainName); | 309 | cifs_sb->tcon->ses->domainName); |
314 | } | 310 | } |
311 | if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) || | ||
312 | !(cifs_sb->tcon->unix_ext)) | ||
313 | seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); | ||
314 | if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) || | ||
315 | !(cifs_sb->tcon->unix_ext)) | ||
316 | seq_printf(s, ",gid=%d", cifs_sb->mnt_gid); | ||
315 | } | 317 | } |
316 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) | 318 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) |
317 | seq_printf(s, ",posixpaths"); | 319 | seq_printf(s, ",posixpaths"); |
318 | if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) || | ||
319 | !(cifs_sb->tcon->unix_ext)) | ||
320 | seq_printf(s, ",uid=%d", cifs_sb->mnt_uid); | ||
321 | if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) || | ||
322 | !(cifs_sb->tcon->unix_ext)) | ||
323 | seq_printf(s, ",gid=%d", cifs_sb->mnt_gid); | ||
324 | seq_printf(s, ",rsize=%d", cifs_sb->rsize); | 320 | seq_printf(s, ",rsize=%d", cifs_sb->rsize); |
325 | seq_printf(s, ",wsize=%d", cifs_sb->wsize); | 321 | seq_printf(s, ",wsize=%d", cifs_sb->wsize); |
326 | } | 322 | } |
@@ -346,7 +342,7 @@ int cifs_xquota_set(struct super_block *sb, int quota_type, qid_t qid, | |||
346 | if (pTcon) { | 342 | if (pTcon) { |
347 | cFYI(1, ("set type: 0x%x id: %d", quota_type, qid)); | 343 | cFYI(1, ("set type: 0x%x id: %d", quota_type, qid)); |
348 | } else { | 344 | } else { |
349 | return -EIO; | 345 | rc = -EIO; |
350 | } | 346 | } |
351 | 347 | ||
352 | FreeXid(xid); | 348 | FreeXid(xid); |
@@ -716,7 +712,7 @@ static int | |||
716 | cifs_init_inodecache(void) | 712 | cifs_init_inodecache(void) |
717 | { | 713 | { |
718 | cifs_inode_cachep = kmem_cache_create("cifs_inode_cache", | 714 | cifs_inode_cachep = kmem_cache_create("cifs_inode_cache", |
719 | sizeof (struct cifsInodeInfo), | 715 | sizeof(struct cifsInodeInfo), |
720 | 0, (SLAB_RECLAIM_ACCOUNT| | 716 | 0, (SLAB_RECLAIM_ACCOUNT| |
721 | SLAB_MEM_SPREAD), | 717 | SLAB_MEM_SPREAD), |
722 | cifs_init_once); | 718 | cifs_init_once); |
@@ -816,8 +812,8 @@ static int | |||
816 | cifs_init_mids(void) | 812 | cifs_init_mids(void) |
817 | { | 813 | { |
818 | cifs_mid_cachep = kmem_cache_create("cifs_mpx_ids", | 814 | cifs_mid_cachep = kmem_cache_create("cifs_mpx_ids", |
819 | sizeof (struct mid_q_entry), 0, | 815 | sizeof(struct mid_q_entry), 0, |
820 | SLAB_HWCACHE_ALIGN, NULL); | 816 | SLAB_HWCACHE_ALIGN, NULL); |
821 | if (cifs_mid_cachep == NULL) | 817 | if (cifs_mid_cachep == NULL) |
822 | return -ENOMEM; | 818 | return -ENOMEM; |
823 | 819 | ||
@@ -829,8 +825,8 @@ cifs_init_mids(void) | |||
829 | } | 825 | } |
830 | 826 | ||
831 | cifs_oplock_cachep = kmem_cache_create("cifs_oplock_structs", | 827 | cifs_oplock_cachep = kmem_cache_create("cifs_oplock_structs", |
832 | sizeof (struct oplock_q_entry), 0, | 828 | sizeof(struct oplock_q_entry), 0, |
833 | SLAB_HWCACHE_ALIGN, NULL); | 829 | SLAB_HWCACHE_ALIGN, NULL); |
834 | if (cifs_oplock_cachep == NULL) { | 830 | if (cifs_oplock_cachep == NULL) { |
835 | mempool_destroy(cifs_mid_poolp); | 831 | mempool_destroy(cifs_mid_poolp); |
836 | kmem_cache_destroy(cifs_mid_cachep); | 832 | kmem_cache_destroy(cifs_mid_cachep); |
@@ -882,7 +878,8 @@ static int cifs_oplock_thread(void *dummyarg) | |||
882 | the call */ | 878 | the call */ |
883 | /* mutex_lock(&inode->i_mutex);*/ | 879 | /* mutex_lock(&inode->i_mutex);*/ |
884 | if (S_ISREG(inode->i_mode)) { | 880 | if (S_ISREG(inode->i_mode)) { |
885 | rc = filemap_fdatawrite(inode->i_mapping); | 881 | rc = |
882 | filemap_fdatawrite(inode->i_mapping); | ||
886 | if (CIFS_I(inode)->clientCanCacheRead | 883 | if (CIFS_I(inode)->clientCanCacheRead |
887 | == 0) { | 884 | == 0) { |
888 | filemap_fdatawait(inode->i_mapping); | 885 | filemap_fdatawait(inode->i_mapping); |
@@ -907,8 +904,7 @@ static int cifs_oplock_thread(void *dummyarg) | |||
907 | 0 /* len */ , 0 /* offset */, 0, | 904 | 0 /* len */ , 0 /* offset */, 0, |
908 | 0, LOCKING_ANDX_OPLOCK_RELEASE, | 905 | 0, LOCKING_ANDX_OPLOCK_RELEASE, |
909 | 0 /* wait flag */); | 906 | 0 /* wait flag */); |
910 | cFYI(1, | 907 | cFYI(1, ("Oplock release rc = %d", rc)); |
911 | ("Oplock release rc = %d ", rc)); | ||
912 | } | 908 | } |
913 | } else | 909 | } else |
914 | spin_unlock(&GlobalMid_Lock); | 910 | spin_unlock(&GlobalMid_Lock); |
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index a20de77a3856..0a3ee5a322b0 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * fs/cifs/cifsfs.h | 2 | * fs/cifs/cifsfs.h |
3 | * | 3 | * |
4 | * Copyright (c) International Business Machines Corp., 2002, 2005 | 4 | * Copyright (c) International Business Machines Corp., 2002, 2007 |
5 | * Author(s): Steve French (sfrench@us.ibm.com) | 5 | * Author(s): Steve French (sfrench@us.ibm.com) |
6 | * | 6 | * |
7 | * This library is free software; you can redistribute it and/or modify | 7 | * This library is free software; you can redistribute it and/or modify |
@@ -99,7 +99,12 @@ extern int cifs_setxattr(struct dentry *, const char *, const void *, | |||
99 | size_t, int); | 99 | size_t, int); |
100 | extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); | 100 | extern ssize_t cifs_getxattr(struct dentry *, const char *, void *, size_t); |
101 | extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); | 101 | extern ssize_t cifs_listxattr(struct dentry *, char *, size_t); |
102 | extern int cifs_ioctl (struct inode *inode, struct file *filep, | 102 | extern int cifs_ioctl(struct inode *inode, struct file *filep, |
103 | unsigned int command, unsigned long arg); | 103 | unsigned int command, unsigned long arg); |
104 | #define CIFS_VERSION "1.50" | 104 | |
105 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
106 | extern struct export_operations cifs_export_ops; | ||
107 | #endif /* EXPERIMENTAL */ | ||
108 | |||
109 | #define CIFS_VERSION "1.51" | ||
105 | #endif /* _CIFSFS_H */ | 110 | #endif /* _CIFSFS_H */ |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index b98742fc3b5a..87f51f23276f 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/in.h> | 19 | #include <linux/in.h> |
20 | #include <linux/in6.h> | 20 | #include <linux/in6.h> |
21 | #include "cifs_fs_sb.h" | 21 | #include "cifs_fs_sb.h" |
22 | #include "cifsacl.h" | ||
22 | /* | 23 | /* |
23 | * The sizes of various internal tables and strings | 24 | * The sizes of various internal tables and strings |
24 | */ | 25 | */ |
@@ -89,7 +90,8 @@ enum statusEnum { | |||
89 | }; | 90 | }; |
90 | 91 | ||
91 | enum securityEnum { | 92 | enum securityEnum { |
92 | LANMAN = 0, /* Legacy LANMAN auth */ | 93 | PLAINTXT = 0, /* Legacy with Plaintext passwords */ |
94 | LANMAN, /* Legacy LANMAN auth */ | ||
93 | NTLM, /* Legacy NTLM012 auth with NTLM hash */ | 95 | NTLM, /* Legacy NTLM012 auth with NTLM hash */ |
94 | NTLMv2, /* Legacy NTLM auth with NTLMv2 hash */ | 96 | NTLMv2, /* Legacy NTLM auth with NTLMv2 hash */ |
95 | RawNTLMSSP, /* NTLMSSP without SPNEGO */ | 97 | RawNTLMSSP, /* NTLMSSP without SPNEGO */ |
@@ -115,6 +117,17 @@ struct mac_key { | |||
115 | } data; | 117 | } data; |
116 | }; | 118 | }; |
117 | 119 | ||
120 | struct cifs_cred { | ||
121 | int uid; | ||
122 | int gid; | ||
123 | int mode; | ||
124 | int cecount; | ||
125 | struct cifs_sid osid; | ||
126 | struct cifs_sid gsid; | ||
127 | struct cifs_ntace *ntaces; | ||
128 | struct cifs_ace *aces; | ||
129 | }; | ||
130 | |||
118 | /* | 131 | /* |
119 | ***************************************************************** | 132 | ***************************************************************** |
120 | * Except the CIFS PDUs themselves all the | 133 | * Except the CIFS PDUs themselves all the |
@@ -279,6 +292,7 @@ struct cifsTconInfo { | |||
279 | FILE_SYSTEM_DEVICE_INFO fsDevInfo; | 292 | FILE_SYSTEM_DEVICE_INFO fsDevInfo; |
280 | FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */ | 293 | FILE_SYSTEM_ATTRIBUTE_INFO fsAttrInfo; /* ok if fs name truncated */ |
281 | FILE_SYSTEM_UNIX_INFO fsUnixInfo; | 294 | FILE_SYSTEM_UNIX_INFO fsUnixInfo; |
295 | unsigned ipc:1; /* set if connection to IPC$ eg for RPC/PIPES */ | ||
282 | unsigned retry:1; | 296 | unsigned retry:1; |
283 | unsigned nocase:1; | 297 | unsigned nocase:1; |
284 | unsigned unix_ext:1; /* if off disable Linux extensions to CIFS protocol | 298 | unsigned unix_ext:1; /* if off disable Linux extensions to CIFS protocol |
@@ -329,6 +343,7 @@ struct cifsFileInfo { | |||
329 | struct list_head llist; /* list of byte range locks we have. */ | 343 | struct list_head llist; /* list of byte range locks we have. */ |
330 | unsigned closePend:1; /* file is marked to close */ | 344 | unsigned closePend:1; /* file is marked to close */ |
331 | unsigned invalidHandle:1; /* file closed via session abend */ | 345 | unsigned invalidHandle:1; /* file closed via session abend */ |
346 | unsigned messageMode:1; /* for pipes: message vs byte mode */ | ||
332 | atomic_t wrtPending; /* handle in use - defer close */ | 347 | atomic_t wrtPending; /* handle in use - defer close */ |
333 | struct semaphore fh_sem; /* prevents reopen race after dead ses*/ | 348 | struct semaphore fh_sem; /* prevents reopen race after dead ses*/ |
334 | char *search_resume_name; /* BB removeme BB */ | 349 | char *search_resume_name; /* BB removeme BB */ |
@@ -464,6 +479,9 @@ struct dir_notify_req { | |||
464 | #ifdef CONFIG_CIFS_WEAK_PW_HASH | 479 | #ifdef CONFIG_CIFS_WEAK_PW_HASH |
465 | #define CIFSSEC_MAY_LANMAN 0x00010 | 480 | #define CIFSSEC_MAY_LANMAN 0x00010 |
466 | #define CIFSSEC_MAY_PLNTXT 0x00020 | 481 | #define CIFSSEC_MAY_PLNTXT 0x00020 |
482 | #else | ||
483 | #define CIFSSEC_MAY_LANMAN 0 | ||
484 | #define CIFSSEC_MAY_PLNTXT 0 | ||
467 | #endif /* weak passwords */ | 485 | #endif /* weak passwords */ |
468 | #define CIFSSEC_MAY_SEAL 0x00040 /* not supported yet */ | 486 | #define CIFSSEC_MAY_SEAL 0x00040 /* not supported yet */ |
469 | 487 | ||
@@ -477,14 +495,23 @@ require use of the stronger protocol */ | |||
477 | #ifdef CONFIG_CIFS_WEAK_PW_HASH | 495 | #ifdef CONFIG_CIFS_WEAK_PW_HASH |
478 | #define CIFSSEC_MUST_LANMAN 0x10010 | 496 | #define CIFSSEC_MUST_LANMAN 0x10010 |
479 | #define CIFSSEC_MUST_PLNTXT 0x20020 | 497 | #define CIFSSEC_MUST_PLNTXT 0x20020 |
498 | #ifdef CONFIG_CIFS_UPCALL | ||
499 | #define CIFSSEC_MASK 0x3F03F /* allows weak security but also krb5 */ | ||
500 | #else | ||
480 | #define CIFSSEC_MASK 0x37037 /* current flags supported if weak */ | 501 | #define CIFSSEC_MASK 0x37037 /* current flags supported if weak */ |
502 | #endif /* UPCALL */ | ||
503 | #else /* do not allow weak pw hash */ | ||
504 | #ifdef CONFIG_CIFS_UPCALL | ||
505 | #define CIFSSEC_MASK 0x0F00F /* flags supported if no weak allowed */ | ||
481 | #else | 506 | #else |
482 | #define CIFSSEC_MASK 0x07007 /* flags supported if no weak config */ | 507 | #define CIFSSEC_MASK 0x07007 /* flags supported if no weak allowed */ |
508 | #endif /* UPCALL */ | ||
483 | #endif /* WEAK_PW_HASH */ | 509 | #endif /* WEAK_PW_HASH */ |
484 | #define CIFSSEC_MUST_SEAL 0x40040 /* not supported yet */ | 510 | #define CIFSSEC_MUST_SEAL 0x40040 /* not supported yet */ |
485 | 511 | ||
486 | #define CIFSSEC_DEF CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 | 512 | #define CIFSSEC_DEF CIFSSEC_MAY_SIGN | CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 |
487 | #define CIFSSEC_MAX CIFSSEC_MUST_SIGN | CIFSSEC_MUST_NTLMV2 | 513 | #define CIFSSEC_MAX CIFSSEC_MUST_SIGN | CIFSSEC_MUST_NTLMV2 |
514 | #define CIFSSEC_AUTH_MASK (CIFSSEC_MAY_NTLM | CIFSSEC_MAY_NTLMV2 | CIFSSEC_MAY_LANMAN | CIFSSEC_MAY_PLNTXT | CIFSSEC_MAY_KRB5) | ||
488 | /* | 515 | /* |
489 | ***************************************************************** | 516 | ***************************************************************** |
490 | * All constants go here | 517 | * All constants go here |
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h index 6a2056e58ceb..c41ff74e9128 100644 --- a/fs/cifs/cifspdu.h +++ b/fs/cifs/cifspdu.h | |||
@@ -215,6 +215,12 @@ | |||
215 | /* file_execute, file_read_attributes*/ | 215 | /* file_execute, file_read_attributes*/ |
216 | /* write_dac, and delete. */ | 216 | /* write_dac, and delete. */ |
217 | 217 | ||
218 | #define FILE_READ_RIGHTS (FILE_READ_DATA | FILE_READ_EA | FILE_READ_ATTRIBUTES) | ||
219 | #define FILE_WRITE_RIGHTS (FILE_WRITE_DATA | FILE_APPEND_DATA \ | ||
220 | | FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES) | ||
221 | #define FILE_EXEC_RIGHTS (FILE_EXECUTE) | ||
222 | |||
223 | |||
218 | /* | 224 | /* |
219 | * Invalid readdir handle | 225 | * Invalid readdir handle |
220 | */ | 226 | */ |
@@ -360,10 +366,10 @@ struct smb_hdr { | |||
360 | __u8 WordCount; | 366 | __u8 WordCount; |
361 | } __attribute__((packed)); | 367 | } __attribute__((packed)); |
362 | /* given a pointer to an smb_hdr retrieve the value of byte count */ | 368 | /* given a pointer to an smb_hdr retrieve the value of byte count */ |
363 | #define BCC(smb_var) ( *(__u16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) ) ) | 369 | #define BCC(smb_var) ( *(__u16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount))) |
364 | #define BCC_LE(smb_var) ( *(__le16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) ) ) | 370 | #define BCC_LE(smb_var) ( *(__le16 *)((char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount))) |
365 | /* given a pointer to an smb_hdr retrieve the pointer to the byte area */ | 371 | /* given a pointer to an smb_hdr retrieve the pointer to the byte area */ |
366 | #define pByteArea(smb_var) ((unsigned char *)smb_var + sizeof(struct smb_hdr) + (2* smb_var->WordCount) + 2 ) | 372 | #define pByteArea(smb_var) ((unsigned char *)smb_var + sizeof(struct smb_hdr) + (2 * smb_var->WordCount) + 2) |
367 | 373 | ||
368 | /* | 374 | /* |
369 | * Computer Name Length (since Netbios name was length 16 with last byte 0x20) | 375 | * Computer Name Length (since Netbios name was length 16 with last byte 0x20) |
@@ -716,6 +722,14 @@ typedef struct smb_com_findclose_req { | |||
716 | #define REQ_OPENDIRONLY 0x00000008 | 722 | #define REQ_OPENDIRONLY 0x00000008 |
717 | #define REQ_EXTENDED_INFO 0x00000010 | 723 | #define REQ_EXTENDED_INFO 0x00000010 |
718 | 724 | ||
725 | /* File type */ | ||
726 | #define DISK_TYPE 0x0000 | ||
727 | #define BYTE_PIPE_TYPE 0x0001 | ||
728 | #define MESSAGE_PIPE_TYPE 0x0002 | ||
729 | #define PRINTER_TYPE 0x0003 | ||
730 | #define COMM_DEV_TYPE 0x0004 | ||
731 | #define UNKNOWN_TYPE 0xFFFF | ||
732 | |||
719 | typedef struct smb_com_open_req { /* also handles create */ | 733 | typedef struct smb_com_open_req { /* also handles create */ |
720 | struct smb_hdr hdr; /* wct = 24 */ | 734 | struct smb_hdr hdr; /* wct = 24 */ |
721 | __u8 AndXCommand; | 735 | __u8 AndXCommand; |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 04a69dafedba..1a883663b22d 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -50,7 +50,8 @@ extern int SendReceive(const unsigned int /* xid */ , struct cifsSesInfo *, | |||
50 | int * /* bytes returned */ , const int long_op); | 50 | int * /* bytes returned */ , const int long_op); |
51 | extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, | 51 | extern int SendReceive2(const unsigned int /* xid */ , struct cifsSesInfo *, |
52 | struct kvec *, int /* nvec to send */, | 52 | struct kvec *, int /* nvec to send */, |
53 | int * /* type of buf returned */ , const int long_op); | 53 | int * /* type of buf returned */ , const int long_op, |
54 | const int logError /* whether to log status code*/ ); | ||
54 | extern int SendReceiveBlockingLock(const unsigned int /* xid */ , | 55 | extern int SendReceiveBlockingLock(const unsigned int /* xid */ , |
55 | struct cifsTconInfo *, | 56 | struct cifsTconInfo *, |
56 | struct smb_hdr * /* input */ , | 57 | struct smb_hdr * /* input */ , |
@@ -65,7 +66,7 @@ extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr); | |||
65 | extern int decode_negTokenInit(unsigned char *security_blob, int length, | 66 | extern int decode_negTokenInit(unsigned char *security_blob, int length, |
66 | enum securityEnum *secType); | 67 | enum securityEnum *secType); |
67 | extern int cifs_inet_pton(int, char *source, void *dst); | 68 | extern int cifs_inet_pton(int, char *source, void *dst); |
68 | extern int map_smb_to_linux_error(struct smb_hdr *smb); | 69 | extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr); |
69 | extern void header_assemble(struct smb_hdr *, char /* command */ , | 70 | extern void header_assemble(struct smb_hdr *, char /* command */ , |
70 | const struct cifsTconInfo *, int /* length of | 71 | const struct cifsTconInfo *, int /* length of |
71 | fixed section (word count) in two byte units */); | 72 | fixed section (word count) in two byte units */); |
@@ -304,12 +305,13 @@ extern int cifs_calculate_mac_key(struct mac_key *key, const char *rn, | |||
304 | const char *pass); | 305 | const char *pass); |
305 | extern int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *, | 306 | extern int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *, |
306 | const struct nls_table *); | 307 | const struct nls_table *); |
307 | extern void CalcNTLMv2_response(const struct cifsSesInfo *, char * ); | 308 | extern void CalcNTLMv2_response(const struct cifsSesInfo *, char *); |
308 | extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *, | 309 | extern void setup_ntlmv2_rsp(struct cifsSesInfo *, char *, |
309 | const struct nls_table *); | 310 | const struct nls_table *); |
310 | #ifdef CONFIG_CIFS_WEAK_PW_HASH | 311 | #ifdef CONFIG_CIFS_WEAK_PW_HASH |
311 | extern void calc_lanman_hash(struct cifsSesInfo *ses, char *lnm_session_key); | 312 | extern void calc_lanman_hash(struct cifsSesInfo *ses, char *lnm_session_key); |
312 | #endif /* CIFS_WEAK_PW_HASH */ | 313 | #endif /* CIFS_WEAK_PW_HASH */ |
314 | extern int parse_sec_desc(struct cifs_ntsd *, int); | ||
313 | extern int CIFSSMBCopy(int xid, | 315 | extern int CIFSSMBCopy(int xid, |
314 | struct cifsTconInfo *source_tcon, | 316 | struct cifsTconInfo *source_tcon, |
315 | const char *fromName, | 317 | const char *fromName, |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 8eb102f940d4..f0d9a485d095 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -34,10 +34,10 @@ | |||
34 | #include <asm/uaccess.h> | 34 | #include <asm/uaccess.h> |
35 | #include "cifspdu.h" | 35 | #include "cifspdu.h" |
36 | #include "cifsglob.h" | 36 | #include "cifsglob.h" |
37 | #include "cifsacl.h" | ||
37 | #include "cifsproto.h" | 38 | #include "cifsproto.h" |
38 | #include "cifs_unicode.h" | 39 | #include "cifs_unicode.h" |
39 | #include "cifs_debug.h" | 40 | #include "cifs_debug.h" |
40 | #include "cifsacl.h" | ||
41 | 41 | ||
42 | #ifdef CONFIG_CIFS_POSIX | 42 | #ifdef CONFIG_CIFS_POSIX |
43 | static struct { | 43 | static struct { |
@@ -94,9 +94,8 @@ static void mark_open_files_invalid(struct cifsTconInfo *pTcon) | |||
94 | write_lock(&GlobalSMBSeslock); | 94 | write_lock(&GlobalSMBSeslock); |
95 | list_for_each_safe(tmp, tmp1, &pTcon->openFileList) { | 95 | list_for_each_safe(tmp, tmp1, &pTcon->openFileList) { |
96 | open_file = list_entry(tmp, struct cifsFileInfo, tlist); | 96 | open_file = list_entry(tmp, struct cifsFileInfo, tlist); |
97 | if (open_file) { | 97 | if (open_file) |
98 | open_file->invalidHandle = TRUE; | 98 | open_file->invalidHandle = TRUE; |
99 | } | ||
100 | } | 99 | } |
101 | write_unlock(&GlobalSMBSeslock); | 100 | write_unlock(&GlobalSMBSeslock); |
102 | /* BB Add call to invalidate_inodes(sb) for all superblocks mounted | 101 | /* BB Add call to invalidate_inodes(sb) for all superblocks mounted |
@@ -439,8 +438,13 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
439 | 438 | ||
440 | pSMB->hdr.Mid = GetNextMid(server); | 439 | pSMB->hdr.Mid = GetNextMid(server); |
441 | pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS); | 440 | pSMB->hdr.Flags2 |= (SMBFLG2_UNICODE | SMBFLG2_ERR_STATUS); |
441 | |||
442 | if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5) | 442 | if ((secFlags & CIFSSEC_MUST_KRB5) == CIFSSEC_MUST_KRB5) |
443 | pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; | 443 | pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; |
444 | else if ((secFlags & CIFSSEC_AUTH_MASK) == CIFSSEC_MAY_KRB5) { | ||
445 | cFYI(1, ("Kerberos only mechanism, enable extended security")); | ||
446 | pSMB->hdr.Flags2 |= SMBFLG2_EXT_SEC; | ||
447 | } | ||
444 | 448 | ||
445 | count = 0; | 449 | count = 0; |
446 | for (i = 0; i < CIFS_NUM_PROT; i++) { | 450 | for (i = 0; i < CIFS_NUM_PROT; i++) { |
@@ -513,7 +517,7 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
513 | (int)ts.tv_sec, (int)utc.tv_sec, | 517 | (int)ts.tv_sec, (int)utc.tv_sec, |
514 | (int)(utc.tv_sec - ts.tv_sec))); | 518 | (int)(utc.tv_sec - ts.tv_sec))); |
515 | val = (int)(utc.tv_sec - ts.tv_sec); | 519 | val = (int)(utc.tv_sec - ts.tv_sec); |
516 | seconds = val < 0 ? -val : val; | 520 | seconds = abs(val); |
517 | result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ; | 521 | result = (seconds / MIN_TZ_ADJ) * MIN_TZ_ADJ; |
518 | remain = seconds % MIN_TZ_ADJ; | 522 | remain = seconds % MIN_TZ_ADJ; |
519 | if (remain >= (MIN_TZ_ADJ / 2)) | 523 | if (remain >= (MIN_TZ_ADJ / 2)) |
@@ -574,7 +578,20 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
574 | server->secType = NTLM; | 578 | server->secType = NTLM; |
575 | else if (secFlags & CIFSSEC_MAY_NTLMV2) | 579 | else if (secFlags & CIFSSEC_MAY_NTLMV2) |
576 | server->secType = NTLMv2; | 580 | server->secType = NTLMv2; |
577 | /* else krb5 ... any others ... */ | 581 | else if (secFlags & CIFSSEC_MAY_KRB5) |
582 | server->secType = Kerberos; | ||
583 | else if (secFlags & CIFSSEC_MAY_LANMAN) | ||
584 | server->secType = LANMAN; | ||
585 | /* #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
586 | else if (secFlags & CIFSSEC_MAY_PLNTXT) | ||
587 | server->secType = ?? | ||
588 | #endif */ | ||
589 | else { | ||
590 | rc = -EOPNOTSUPP; | ||
591 | cERROR(1, ("Invalid security type")); | ||
592 | goto neg_err_exit; | ||
593 | } | ||
594 | /* else ... any others ...? */ | ||
578 | 595 | ||
579 | /* one byte, so no need to convert this or EncryptionKeyLen from | 596 | /* one byte, so no need to convert this or EncryptionKeyLen from |
580 | little endian */ | 597 | little endian */ |
@@ -604,22 +621,26 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) | |||
604 | if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) && | 621 | if ((pSMBr->hdr.Flags2 & SMBFLG2_EXT_SEC) && |
605 | (server->capabilities & CAP_EXTENDED_SECURITY)) { | 622 | (server->capabilities & CAP_EXTENDED_SECURITY)) { |
606 | count = pSMBr->ByteCount; | 623 | count = pSMBr->ByteCount; |
607 | if (count < 16) | 624 | if (count < 16) { |
608 | rc = -EIO; | 625 | rc = -EIO; |
609 | else if (count == 16) { | 626 | goto neg_err_exit; |
610 | server->secType = RawNTLMSSP; | 627 | } |
611 | if (server->socketUseCount.counter > 1) { | 628 | |
612 | if (memcmp(server->server_GUID, | 629 | if (server->socketUseCount.counter > 1) { |
613 | pSMBr->u.extended_response. | 630 | if (memcmp(server->server_GUID, |
614 | GUID, 16) != 0) { | 631 | pSMBr->u.extended_response. |
615 | cFYI(1, ("server UID changed")); | 632 | GUID, 16) != 0) { |
616 | memcpy(server->server_GUID, | 633 | cFYI(1, ("server UID changed")); |
617 | pSMBr->u.extended_response.GUID, | ||
618 | 16); | ||
619 | } | ||
620 | } else | ||
621 | memcpy(server->server_GUID, | 634 | memcpy(server->server_GUID, |
622 | pSMBr->u.extended_response.GUID, 16); | 635 | pSMBr->u.extended_response.GUID, |
636 | 16); | ||
637 | } | ||
638 | } else | ||
639 | memcpy(server->server_GUID, | ||
640 | pSMBr->u.extended_response.GUID, 16); | ||
641 | |||
642 | if (count == 16) { | ||
643 | server->secType = RawNTLMSSP; | ||
623 | } else { | 644 | } else { |
624 | rc = decode_negTokenInit(pSMBr->u.extended_response. | 645 | rc = decode_negTokenInit(pSMBr->u.extended_response. |
625 | SecurityBlob, | 646 | SecurityBlob, |
@@ -642,10 +663,12 @@ signing_check: | |||
642 | /* MUST_SIGN already includes the MAY_SIGN FLAG | 663 | /* MUST_SIGN already includes the MAY_SIGN FLAG |
643 | so if this is zero it means that signing is disabled */ | 664 | so if this is zero it means that signing is disabled */ |
644 | cFYI(1, ("Signing disabled")); | 665 | cFYI(1, ("Signing disabled")); |
645 | if (server->secMode & SECMODE_SIGN_REQUIRED) | 666 | if (server->secMode & SECMODE_SIGN_REQUIRED) { |
646 | cERROR(1, ("Server requires " | 667 | cERROR(1, ("Server requires " |
647 | "/proc/fs/cifs/PacketSigningEnabled " | 668 | "packet signing to be enabled in " |
648 | "to be on")); | 669 | "/proc/fs/cifs/SecurityFlags.")); |
670 | rc = -EOPNOTSUPP; | ||
671 | } | ||
649 | server->secMode &= | 672 | server->secMode &= |
650 | ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); | 673 | ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); |
651 | } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) { | 674 | } else if ((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) { |
@@ -1052,7 +1075,7 @@ PsxCreat: | |||
1052 | InformationLevel) - 4; | 1075 | InformationLevel) - 4; |
1053 | offset = param_offset + params; | 1076 | offset = param_offset + params; |
1054 | pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset); | 1077 | pdata = (OPEN_PSX_REQ *)(((char *)&pSMB->hdr.Protocol) + offset); |
1055 | pdata->Level = SMB_QUERY_FILE_UNIX_BASIC; | 1078 | pdata->Level = cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC); |
1056 | pdata->Permissions = cpu_to_le64(mode); | 1079 | pdata->Permissions = cpu_to_le64(mode); |
1057 | pdata->PosixOpenFlags = cpu_to_le32(posix_flags); | 1080 | pdata->PosixOpenFlags = cpu_to_le32(posix_flags); |
1058 | pdata->OpenFlags = cpu_to_le32(*pOplock); | 1081 | pdata->OpenFlags = cpu_to_le32(*pOplock); |
@@ -1098,8 +1121,8 @@ PsxCreat: | |||
1098 | if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction) | 1121 | if (cpu_to_le32(FILE_CREATE) == psx_rsp->CreateAction) |
1099 | *pOplock |= CIFS_CREATE_ACTION; | 1122 | *pOplock |= CIFS_CREATE_ACTION; |
1100 | /* check to make sure response data is there */ | 1123 | /* check to make sure response data is there */ |
1101 | if (psx_rsp->ReturnedLevel != SMB_QUERY_FILE_UNIX_BASIC) { | 1124 | if (psx_rsp->ReturnedLevel != cpu_to_le16(SMB_QUERY_FILE_UNIX_BASIC)) { |
1102 | pRetData->Type = -1; /* unknown */ | 1125 | pRetData->Type = cpu_to_le32(-1); /* unknown */ |
1103 | #ifdef CONFIG_CIFS_DEBUG2 | 1126 | #ifdef CONFIG_CIFS_DEBUG2 |
1104 | cFYI(1, ("unknown type")); | 1127 | cFYI(1, ("unknown type")); |
1105 | #endif | 1128 | #endif |
@@ -1107,12 +1130,12 @@ PsxCreat: | |||
1107 | if (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP) | 1130 | if (pSMBr->ByteCount < sizeof(OPEN_PSX_RSP) |
1108 | + sizeof(FILE_UNIX_BASIC_INFO)) { | 1131 | + sizeof(FILE_UNIX_BASIC_INFO)) { |
1109 | cERROR(1, ("Open response data too small")); | 1132 | cERROR(1, ("Open response data too small")); |
1110 | pRetData->Type = -1; | 1133 | pRetData->Type = cpu_to_le32(-1); |
1111 | goto psx_create_err; | 1134 | goto psx_create_err; |
1112 | } | 1135 | } |
1113 | memcpy((char *) pRetData, | 1136 | memcpy((char *) pRetData, |
1114 | (char *)psx_rsp + sizeof(OPEN_PSX_RSP), | 1137 | (char *)psx_rsp + sizeof(OPEN_PSX_RSP), |
1115 | sizeof (FILE_UNIX_BASIC_INFO)); | 1138 | sizeof(FILE_UNIX_BASIC_INFO)); |
1116 | } | 1139 | } |
1117 | 1140 | ||
1118 | psx_create_err: | 1141 | psx_create_err: |
@@ -1193,9 +1216,9 @@ OldOpenRetry: | |||
1193 | } | 1216 | } |
1194 | if (*pOplock & REQ_OPLOCK) | 1217 | if (*pOplock & REQ_OPLOCK) |
1195 | pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK); | 1218 | pSMB->OpenFlags = cpu_to_le16(REQ_OPLOCK); |
1196 | else if (*pOplock & REQ_BATCHOPLOCK) { | 1219 | else if (*pOplock & REQ_BATCHOPLOCK) |
1197 | pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK); | 1220 | pSMB->OpenFlags = cpu_to_le16(REQ_BATCHOPLOCK); |
1198 | } | 1221 | |
1199 | pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO); | 1222 | pSMB->OpenFlags |= cpu_to_le16(REQ_MORE_INFO); |
1200 | /* BB fixme add conversion for access_flags to bits 0 - 2 of mode */ | 1223 | /* BB fixme add conversion for access_flags to bits 0 - 2 of mode */ |
1201 | /* 0 = read | 1224 | /* 0 = read |
@@ -1310,9 +1333,8 @@ openRetry: | |||
1310 | } | 1333 | } |
1311 | if (*pOplock & REQ_OPLOCK) | 1334 | if (*pOplock & REQ_OPLOCK) |
1312 | pSMB->OpenFlags = cpu_to_le32(REQ_OPLOCK); | 1335 | pSMB->OpenFlags = cpu_to_le32(REQ_OPLOCK); |
1313 | else if (*pOplock & REQ_BATCHOPLOCK) { | 1336 | else if (*pOplock & REQ_BATCHOPLOCK) |
1314 | pSMB->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK); | 1337 | pSMB->OpenFlags = cpu_to_le32(REQ_BATCHOPLOCK); |
1315 | } | ||
1316 | pSMB->DesiredAccess = cpu_to_le32(access_flags); | 1338 | pSMB->DesiredAccess = cpu_to_le32(access_flags); |
1317 | pSMB->AllocationSize = 0; | 1339 | pSMB->AllocationSize = 0; |
1318 | /* set file as system file if special file such | 1340 | /* set file as system file if special file such |
@@ -1424,9 +1446,8 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid, | |||
1424 | 1446 | ||
1425 | iov[0].iov_base = (char *)pSMB; | 1447 | iov[0].iov_base = (char *)pSMB; |
1426 | iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; | 1448 | iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; |
1427 | rc = SendReceive2(xid, tcon->ses, iov, | 1449 | rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovecs */, |
1428 | 1 /* num iovecs */, | 1450 | &resp_buf_type, 0 /* not long op */, 1 /* log err */ ); |
1429 | &resp_buf_type, 0); | ||
1430 | cifs_stats_inc(&tcon->num_reads); | 1451 | cifs_stats_inc(&tcon->num_reads); |
1431 | pSMBr = (READ_RSP *)iov[0].iov_base; | 1452 | pSMBr = (READ_RSP *)iov[0].iov_base; |
1432 | if (rc) { | 1453 | if (rc) { |
@@ -1446,11 +1467,11 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid, | |||
1446 | *nbytes = 0; | 1467 | *nbytes = 0; |
1447 | } else { | 1468 | } else { |
1448 | pReadData = (char *) (&pSMBr->hdr.Protocol) + | 1469 | pReadData = (char *) (&pSMBr->hdr.Protocol) + |
1449 | le16_to_cpu(pSMBr->DataOffset); | 1470 | le16_to_cpu(pSMBr->DataOffset); |
1450 | /* if (rc = copy_to_user(buf, pReadData, data_length)) { | 1471 | /* if (rc = copy_to_user(buf, pReadData, data_length)) { |
1451 | cERROR(1,("Faulting on read rc = %d",rc)); | 1472 | cERROR(1,("Faulting on read rc = %d",rc)); |
1452 | rc = -EFAULT; | 1473 | rc = -EFAULT; |
1453 | }*/ /* can not use copy_to_user when using page cache*/ | 1474 | }*/ /* can not use copy_to_user when using page cache*/ |
1454 | if (*buf) | 1475 | if (*buf) |
1455 | memcpy(*buf, pReadData, data_length); | 1476 | memcpy(*buf, pReadData, data_length); |
1456 | } | 1477 | } |
@@ -1645,7 +1666,7 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon, | |||
1645 | 1666 | ||
1646 | 1667 | ||
1647 | rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, | 1668 | rc = SendReceive2(xid, tcon->ses, iov, n_vec + 1, &resp_buf_type, |
1648 | long_op); | 1669 | long_op, 0 /* do not log STATUS code */ ); |
1649 | cifs_stats_inc(&tcon->num_writes); | 1670 | cifs_stats_inc(&tcon->num_writes); |
1650 | if (rc) { | 1671 | if (rc) { |
1651 | cFYI(1, ("Send error Write2 = %d", rc)); | 1672 | cFYI(1, ("Send error Write2 = %d", rc)); |
@@ -2538,7 +2559,7 @@ validate_ntransact(char *buf, char **ppparm, char **ppdata, | |||
2538 | cFYI(1, ("data starts after end of smb")); | 2559 | cFYI(1, ("data starts after end of smb")); |
2539 | return -EINVAL; | 2560 | return -EINVAL; |
2540 | } else if (data_count + *ppdata > end_of_smb) { | 2561 | } else if (data_count + *ppdata > end_of_smb) { |
2541 | cFYI(1,("data %p + count %d (%p) ends after end of smb %p start %p", | 2562 | cFYI(1, ("data %p + count %d (%p) ends after end of smb %p start %p", |
2542 | *ppdata, data_count, (data_count + *ppdata), | 2563 | *ppdata, data_count, (data_count + *ppdata), |
2543 | end_of_smb, pSMBr)); | 2564 | end_of_smb, pSMBr)); |
2544 | return -EINVAL; | 2565 | return -EINVAL; |
@@ -2615,7 +2636,7 @@ CIFSSMBQueryReparseLinkInfo(const int xid, struct cifsTconInfo *tcon, | |||
2615 | reparse_buf->TargetNameOffset + | 2636 | reparse_buf->TargetNameOffset + |
2616 | reparse_buf->TargetNameLen) > | 2637 | reparse_buf->TargetNameLen) > |
2617 | end_of_smb) { | 2638 | end_of_smb) { |
2618 | cFYI(1,("reparse buf goes beyond SMB")); | 2639 | cFYI(1, ("reparse buf beyond SMB")); |
2619 | rc = -EIO; | 2640 | rc = -EIO; |
2620 | goto qreparse_out; | 2641 | goto qreparse_out; |
2621 | } | 2642 | } |
@@ -3042,25 +3063,12 @@ GetExtAttrOut: | |||
3042 | 3063 | ||
3043 | #endif /* CONFIG_POSIX */ | 3064 | #endif /* CONFIG_POSIX */ |
3044 | 3065 | ||
3045 | 3066 | #ifdef CONFIG_CIFS_EXPERIMENTAL | |
3046 | /* security id for everyone */ | ||
3047 | static const struct cifs_sid sid_everyone = | ||
3048 | {1, 1, {0, 0, 0, 0, 0, 0}, {0, 0, 0, 0}}; | ||
3049 | /* group users */ | ||
3050 | static const struct cifs_sid sid_user = | ||
3051 | {1, 2 , {0, 0, 0, 0, 0, 5}, {32, 545, 0, 0}}; | ||
3052 | |||
3053 | /* Convert CIFS ACL to POSIX form */ | ||
3054 | static int parse_sec_desc(struct cifs_sid *psec_desc, int acl_len) | ||
3055 | { | ||
3056 | return 0; | ||
3057 | } | ||
3058 | |||
3059 | /* Get Security Descriptor (by handle) from remote server for a file or dir */ | 3067 | /* Get Security Descriptor (by handle) from remote server for a file or dir */ |
3060 | int | 3068 | int |
3061 | CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, | 3069 | CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, |
3062 | /* BB fix up return info */ char *acl_inf, const int buflen, | 3070 | /* BB fix up return info */ char *acl_inf, const int buflen, |
3063 | const int acl_type /* ACCESS/DEFAULT not sure implication */) | 3071 | const int acl_type) |
3064 | { | 3072 | { |
3065 | int rc = 0; | 3073 | int rc = 0; |
3066 | int buf_type = 0; | 3074 | int buf_type = 0; |
@@ -3085,12 +3093,13 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, | |||
3085 | iov[0].iov_base = (char *)pSMB; | 3093 | iov[0].iov_base = (char *)pSMB; |
3086 | iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; | 3094 | iov[0].iov_len = pSMB->hdr.smb_buf_length + 4; |
3087 | 3095 | ||
3088 | rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, 0); | 3096 | rc = SendReceive2(xid, tcon->ses, iov, 1 /* num iovec */, &buf_type, |
3097 | 0 /* not long op */, 0 /* do not log STATUS codes */ ); | ||
3089 | cifs_stats_inc(&tcon->num_acl_get); | 3098 | cifs_stats_inc(&tcon->num_acl_get); |
3090 | if (rc) { | 3099 | if (rc) { |
3091 | cFYI(1, ("Send error in QuerySecDesc = %d", rc)); | 3100 | cFYI(1, ("Send error in QuerySecDesc = %d", rc)); |
3092 | } else { /* decode response */ | 3101 | } else { /* decode response */ |
3093 | struct cifs_sid *psec_desc; | 3102 | struct cifs_ntsd *psec_desc; |
3094 | __le32 * parm; | 3103 | __le32 * parm; |
3095 | int parm_len; | 3104 | int parm_len; |
3096 | int data_len; | 3105 | int data_len; |
@@ -3105,8 +3114,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, | |||
3105 | goto qsec_out; | 3114 | goto qsec_out; |
3106 | pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base; | 3115 | pSMBr = (struct smb_com_ntransact_rsp *)iov[0].iov_base; |
3107 | 3116 | ||
3108 | cERROR(1, ("smb %p parm %p data %p", | 3117 | cFYI(1, ("smb %p parm %p data %p", pSMBr, parm, psec_desc)); |
3109 | pSMBr, parm, psec_desc)); /* BB removeme BB */ | ||
3110 | 3118 | ||
3111 | if (le32_to_cpu(pSMBr->ParameterCount) != 4) { | 3119 | if (le32_to_cpu(pSMBr->ParameterCount) != 4) { |
3112 | rc = -EIO; /* bad smb */ | 3120 | rc = -EIO; /* bad smb */ |
@@ -3115,7 +3123,7 @@ CIFSSMBGetCIFSACL(const int xid, struct cifsTconInfo *tcon, __u16 fid, | |||
3115 | 3123 | ||
3116 | /* BB check that data area is minimum length and as big as acl_len */ | 3124 | /* BB check that data area is minimum length and as big as acl_len */ |
3117 | 3125 | ||
3118 | acl_len = le32_to_cpu(*(__le32 *)parm); | 3126 | acl_len = le32_to_cpu(*parm); |
3119 | /* BB check if (acl_len > bufsize) */ | 3127 | /* BB check if (acl_len > bufsize) */ |
3120 | 3128 | ||
3121 | parse_sec_desc(psec_desc, acl_len); | 3129 | parse_sec_desc(psec_desc, acl_len); |
@@ -3128,6 +3136,7 @@ qsec_out: | |||
3128 | /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ | 3136 | /* cifs_small_buf_release(pSMB); */ /* Freed earlier now in SendReceive2 */ |
3129 | return rc; | 3137 | return rc; |
3130 | } | 3138 | } |
3139 | #endif /* CONFIG_CIFS_EXPERIMENTAL */ | ||
3131 | 3140 | ||
3132 | /* Legacy Query Path Information call for lookup to old servers such | 3141 | /* Legacy Query Path Information call for lookup to old servers such |
3133 | as Win9x/WinME */ | 3142 | as Win9x/WinME */ |
@@ -3363,6 +3372,9 @@ UnixQPathInfoRetry: | |||
3363 | rc = validate_t2((struct smb_t2_rsp *)pSMBr); | 3372 | rc = validate_t2((struct smb_t2_rsp *)pSMBr); |
3364 | 3373 | ||
3365 | if (rc || (pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO))) { | 3374 | if (rc || (pSMBr->ByteCount < sizeof(FILE_UNIX_BASIC_INFO))) { |
3375 | cERROR(1, ("Malformed FILE_UNIX_BASIC_INFO response.\n" | ||
3376 | "Unix Extensions can be disabled on mount " | ||
3377 | "by specifying the nosfu mount option.")); | ||
3366 | rc = -EIO; /* bad smb */ | 3378 | rc = -EIO; /* bad smb */ |
3367 | } else { | 3379 | } else { |
3368 | __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); | 3380 | __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); |
@@ -3883,12 +3895,10 @@ getDFSRetry: | |||
3883 | pSMB->hdr.Mid = GetNextMid(ses->server); | 3895 | pSMB->hdr.Mid = GetNextMid(ses->server); |
3884 | pSMB->hdr.Tid = ses->ipc_tid; | 3896 | pSMB->hdr.Tid = ses->ipc_tid; |
3885 | pSMB->hdr.Uid = ses->Suid; | 3897 | pSMB->hdr.Uid = ses->Suid; |
3886 | if (ses->capabilities & CAP_STATUS32) { | 3898 | if (ses->capabilities & CAP_STATUS32) |
3887 | pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS; | 3899 | pSMB->hdr.Flags2 |= SMBFLG2_ERR_STATUS; |
3888 | } | 3900 | if (ses->capabilities & CAP_DFS) |
3889 | if (ses->capabilities & CAP_DFS) { | ||
3890 | pSMB->hdr.Flags2 |= SMBFLG2_DFS; | 3901 | pSMB->hdr.Flags2 |= SMBFLG2_DFS; |
3891 | } | ||
3892 | 3902 | ||
3893 | if (ses->capabilities & CAP_UNICODE) { | 3903 | if (ses->capabilities & CAP_UNICODE) { |
3894 | pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; | 3904 | pSMB->hdr.Flags2 |= SMBFLG2_UNICODE; |
@@ -4060,10 +4070,6 @@ oldQFSInfoRetry: | |||
4060 | (void **) &pSMBr); | 4070 | (void **) &pSMBr); |
4061 | if (rc) | 4071 | if (rc) |
4062 | return rc; | 4072 | return rc; |
4063 | rc = smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB, | ||
4064 | (void **) &pSMBr); | ||
4065 | if (rc) | ||
4066 | return rc; | ||
4067 | 4073 | ||
4068 | params = 2; /* level */ | 4074 | params = 2; /* level */ |
4069 | pSMB->TotalDataCount = 0; | 4075 | pSMB->TotalDataCount = 0; |
@@ -4265,7 +4271,7 @@ QFSAttributeRetry: | |||
4265 | *) (((char *) &pSMBr->hdr.Protocol) + | 4271 | *) (((char *) &pSMBr->hdr.Protocol) + |
4266 | data_offset); | 4272 | data_offset); |
4267 | memcpy(&tcon->fsAttrInfo, response_data, | 4273 | memcpy(&tcon->fsAttrInfo, response_data, |
4268 | sizeof (FILE_SYSTEM_ATTRIBUTE_INFO)); | 4274 | sizeof(FILE_SYSTEM_ATTRIBUTE_INFO)); |
4269 | } | 4275 | } |
4270 | } | 4276 | } |
4271 | cifs_buf_release(pSMB); | 4277 | cifs_buf_release(pSMB); |
@@ -4334,7 +4340,7 @@ QFSDeviceRetry: | |||
4334 | (((char *) &pSMBr->hdr.Protocol) + | 4340 | (((char *) &pSMBr->hdr.Protocol) + |
4335 | data_offset); | 4341 | data_offset); |
4336 | memcpy(&tcon->fsDevInfo, response_data, | 4342 | memcpy(&tcon->fsDevInfo, response_data, |
4337 | sizeof (FILE_SYSTEM_DEVICE_INFO)); | 4343 | sizeof(FILE_SYSTEM_DEVICE_INFO)); |
4338 | } | 4344 | } |
4339 | } | 4345 | } |
4340 | cifs_buf_release(pSMB); | 4346 | cifs_buf_release(pSMB); |
@@ -4402,7 +4408,7 @@ QFSUnixRetry: | |||
4402 | *) (((char *) &pSMBr->hdr.Protocol) + | 4408 | *) (((char *) &pSMBr->hdr.Protocol) + |
4403 | data_offset); | 4409 | data_offset); |
4404 | memcpy(&tcon->fsUnixInfo, response_data, | 4410 | memcpy(&tcon->fsUnixInfo, response_data, |
4405 | sizeof (FILE_SYSTEM_UNIX_INFO)); | 4411 | sizeof(FILE_SYSTEM_UNIX_INFO)); |
4406 | } | 4412 | } |
4407 | } | 4413 | } |
4408 | cifs_buf_release(pSMB); | 4414 | cifs_buf_release(pSMB); |
@@ -4612,7 +4618,7 @@ SetEOFRetry: | |||
4612 | strncpy(pSMB->FileName, fileName, name_len); | 4618 | strncpy(pSMB->FileName, fileName, name_len); |
4613 | } | 4619 | } |
4614 | params = 6 + name_len; | 4620 | params = 6 + name_len; |
4615 | data_count = sizeof (struct file_end_of_file_info); | 4621 | data_count = sizeof(struct file_end_of_file_info); |
4616 | pSMB->MaxParameterCount = cpu_to_le16(2); | 4622 | pSMB->MaxParameterCount = cpu_to_le16(2); |
4617 | pSMB->MaxDataCount = cpu_to_le16(4100); | 4623 | pSMB->MaxDataCount = cpu_to_le16(4100); |
4618 | pSMB->MaxSetupCount = 0; | 4624 | pSMB->MaxSetupCount = 0; |
@@ -4800,7 +4806,7 @@ CIFSSMBSetFileTimes(const int xid, struct cifsTconInfo *tcon, | |||
4800 | 4806 | ||
4801 | data_offset = (char *) (&pSMB->hdr.Protocol) + offset; | 4807 | data_offset = (char *) (&pSMB->hdr.Protocol) + offset; |
4802 | 4808 | ||
4803 | count = sizeof (FILE_BASIC_INFO); | 4809 | count = sizeof(FILE_BASIC_INFO); |
4804 | pSMB->MaxParameterCount = cpu_to_le16(2); | 4810 | pSMB->MaxParameterCount = cpu_to_le16(2); |
4805 | pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */ | 4811 | pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find max SMB PDU from sess */ |
4806 | pSMB->SetupCount = 1; | 4812 | pSMB->SetupCount = 1; |
@@ -4871,7 +4877,7 @@ SetTimesRetry: | |||
4871 | } | 4877 | } |
4872 | 4878 | ||
4873 | params = 6 + name_len; | 4879 | params = 6 + name_len; |
4874 | count = sizeof (FILE_BASIC_INFO); | 4880 | count = sizeof(FILE_BASIC_INFO); |
4875 | pSMB->MaxParameterCount = cpu_to_le16(2); | 4881 | pSMB->MaxParameterCount = cpu_to_le16(2); |
4876 | pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */ | 4882 | pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */ |
4877 | pSMB->MaxSetupCount = 0; | 4883 | pSMB->MaxSetupCount = 0; |
@@ -4900,7 +4906,7 @@ SetTimesRetry: | |||
4900 | pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO); | 4906 | pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_BASIC_INFO); |
4901 | pSMB->Reserved4 = 0; | 4907 | pSMB->Reserved4 = 0; |
4902 | pSMB->hdr.smb_buf_length += byte_count; | 4908 | pSMB->hdr.smb_buf_length += byte_count; |
4903 | memcpy(data_offset, data, sizeof (FILE_BASIC_INFO)); | 4909 | memcpy(data_offset, data, sizeof(FILE_BASIC_INFO)); |
4904 | pSMB->ByteCount = cpu_to_le16(byte_count); | 4910 | pSMB->ByteCount = cpu_to_le16(byte_count); |
4905 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, | 4911 | rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB, |
4906 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); | 4912 | (struct smb_hdr *) pSMBr, &bytes_returned, 0); |
@@ -5003,7 +5009,7 @@ setPermsRetry: | |||
5003 | } | 5009 | } |
5004 | 5010 | ||
5005 | params = 6 + name_len; | 5011 | params = 6 + name_len; |
5006 | count = sizeof (FILE_UNIX_BASIC_INFO); | 5012 | count = sizeof(FILE_UNIX_BASIC_INFO); |
5007 | pSMB->MaxParameterCount = cpu_to_le16(2); | 5013 | pSMB->MaxParameterCount = cpu_to_le16(2); |
5008 | pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */ | 5014 | pSMB->MaxDataCount = cpu_to_le16(1000); /* BB find exact max SMB PDU from sess structure BB */ |
5009 | pSMB->MaxSetupCount = 0; | 5015 | pSMB->MaxSetupCount = 0; |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 4af3588c1a96..19ee11f7f35a 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -124,7 +124,7 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
124 | struct mid_q_entry *mid_entry; | 124 | struct mid_q_entry *mid_entry; |
125 | 125 | ||
126 | spin_lock(&GlobalMid_Lock); | 126 | spin_lock(&GlobalMid_Lock); |
127 | if ( kthread_should_stop() ) { | 127 | if (kthread_should_stop()) { |
128 | /* the demux thread will exit normally | 128 | /* the demux thread will exit normally |
129 | next time through the loop */ | 129 | next time through the loop */ |
130 | spin_unlock(&GlobalMid_Lock); | 130 | spin_unlock(&GlobalMid_Lock); |
@@ -151,9 +151,8 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
151 | } | 151 | } |
152 | list_for_each(tmp, &GlobalTreeConnectionList) { | 152 | list_for_each(tmp, &GlobalTreeConnectionList) { |
153 | tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); | 153 | tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList); |
154 | if ((tcon) && (tcon->ses) && (tcon->ses->server == server)) { | 154 | if ((tcon) && (tcon->ses) && (tcon->ses->server == server)) |
155 | tcon->tidStatus = CifsNeedReconnect; | 155 | tcon->tidStatus = CifsNeedReconnect; |
156 | } | ||
157 | } | 156 | } |
158 | read_unlock(&GlobalSMBSeslock); | 157 | read_unlock(&GlobalSMBSeslock); |
159 | /* do not want to be sending data on a socket we are freeing */ | 158 | /* do not want to be sending data on a socket we are freeing */ |
@@ -187,7 +186,7 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
187 | spin_unlock(&GlobalMid_Lock); | 186 | spin_unlock(&GlobalMid_Lock); |
188 | up(&server->tcpSem); | 187 | up(&server->tcpSem); |
189 | 188 | ||
190 | while ( (!kthread_should_stop()) && (server->tcpStatus != CifsGood)) { | 189 | while ((!kthread_should_stop()) && (server->tcpStatus != CifsGood)) { |
191 | try_to_freeze(); | 190 | try_to_freeze(); |
192 | if (server->protocolType == IPV6) { | 191 | if (server->protocolType == IPV6) { |
193 | rc = ipv6_connect(&server->addr.sockAddr6, | 192 | rc = ipv6_connect(&server->addr.sockAddr6, |
@@ -204,7 +203,7 @@ cifs_reconnect(struct TCP_Server_Info *server) | |||
204 | } else { | 203 | } else { |
205 | atomic_inc(&tcpSesReconnectCount); | 204 | atomic_inc(&tcpSesReconnectCount); |
206 | spin_lock(&GlobalMid_Lock); | 205 | spin_lock(&GlobalMid_Lock); |
207 | if ( !kthread_should_stop() ) | 206 | if (!kthread_should_stop()) |
208 | server->tcpStatus = CifsGood; | 207 | server->tcpStatus = CifsGood; |
209 | server->sequence_number = 0; | 208 | server->sequence_number = 0; |
210 | spin_unlock(&GlobalMid_Lock); | 209 | spin_unlock(&GlobalMid_Lock); |
@@ -352,17 +351,15 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
352 | 351 | ||
353 | current->flags |= PF_MEMALLOC; | 352 | current->flags |= PF_MEMALLOC; |
354 | server->tsk = current; /* save process info to wake at shutdown */ | 353 | server->tsk = current; /* save process info to wake at shutdown */ |
355 | cFYI(1, ("Demultiplex PID: %d", current->pid)); | 354 | cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current))); |
356 | write_lock(&GlobalSMBSeslock); | 355 | write_lock(&GlobalSMBSeslock); |
357 | atomic_inc(&tcpSesAllocCount); | 356 | atomic_inc(&tcpSesAllocCount); |
358 | length = tcpSesAllocCount.counter; | 357 | length = tcpSesAllocCount.counter; |
359 | write_unlock(&GlobalSMBSeslock); | 358 | write_unlock(&GlobalSMBSeslock); |
360 | complete(&cifsd_complete); | 359 | complete(&cifsd_complete); |
361 | if (length > 1) { | 360 | if (length > 1) |
362 | mempool_resize(cifs_req_poolp, | 361 | mempool_resize(cifs_req_poolp, length + cifs_min_rcv, |
363 | length + cifs_min_rcv, | 362 | GFP_KERNEL); |
364 | GFP_KERNEL); | ||
365 | } | ||
366 | 363 | ||
367 | set_freezable(); | 364 | set_freezable(); |
368 | while (!kthread_should_stop()) { | 365 | while (!kthread_should_stop()) { |
@@ -378,7 +375,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
378 | } | 375 | } |
379 | } else if (isLargeBuf) { | 376 | } else if (isLargeBuf) { |
380 | /* we are reusing a dirty large buf, clear its start */ | 377 | /* we are reusing a dirty large buf, clear its start */ |
381 | memset(bigbuf, 0, sizeof (struct smb_hdr)); | 378 | memset(bigbuf, 0, sizeof(struct smb_hdr)); |
382 | } | 379 | } |
383 | 380 | ||
384 | if (smallbuf == NULL) { | 381 | if (smallbuf == NULL) { |
@@ -391,7 +388,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
391 | } | 388 | } |
392 | /* beginning of smb buffer is cleared in our buf_get */ | 389 | /* beginning of smb buffer is cleared in our buf_get */ |
393 | } else /* if existing small buf clear beginning */ | 390 | } else /* if existing small buf clear beginning */ |
394 | memset(smallbuf, 0, sizeof (struct smb_hdr)); | 391 | memset(smallbuf, 0, sizeof(struct smb_hdr)); |
395 | 392 | ||
396 | isLargeBuf = FALSE; | 393 | isLargeBuf = FALSE; |
397 | isMultiRsp = FALSE; | 394 | isMultiRsp = FALSE; |
@@ -400,11 +397,13 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
400 | iov.iov_len = 4; | 397 | iov.iov_len = 4; |
401 | smb_msg.msg_control = NULL; | 398 | smb_msg.msg_control = NULL; |
402 | smb_msg.msg_controllen = 0; | 399 | smb_msg.msg_controllen = 0; |
400 | pdu_length = 4; /* enough to get RFC1001 header */ | ||
401 | incomplete_rcv: | ||
403 | length = | 402 | length = |
404 | kernel_recvmsg(csocket, &smb_msg, | 403 | kernel_recvmsg(csocket, &smb_msg, |
405 | &iov, 1, 4, 0 /* BB see socket.h flags */); | 404 | &iov, 1, pdu_length, 0 /* BB other flags? */); |
406 | 405 | ||
407 | if ( kthread_should_stop() ) { | 406 | if (kthread_should_stop()) { |
408 | break; | 407 | break; |
409 | } else if (server->tcpStatus == CifsNeedReconnect) { | 408 | } else if (server->tcpStatus == CifsNeedReconnect) { |
410 | cFYI(1, ("Reconnect after server stopped responding")); | 409 | cFYI(1, ("Reconnect after server stopped responding")); |
@@ -416,7 +415,10 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
416 | msleep(1); /* minimum sleep to prevent looping | 415 | msleep(1); /* minimum sleep to prevent looping |
417 | allowing socket to clear and app threads to set | 416 | allowing socket to clear and app threads to set |
418 | tcpStatus CifsNeedReconnect if server hung */ | 417 | tcpStatus CifsNeedReconnect if server hung */ |
419 | continue; | 418 | if (pdu_length < 4) |
419 | goto incomplete_rcv; | ||
420 | else | ||
421 | continue; | ||
420 | } else if (length <= 0) { | 422 | } else if (length <= 0) { |
421 | if (server->tcpStatus == CifsNew) { | 423 | if (server->tcpStatus == CifsNew) { |
422 | cFYI(1, ("tcp session abend after SMBnegprot")); | 424 | cFYI(1, ("tcp session abend after SMBnegprot")); |
@@ -437,13 +439,11 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
437 | wake_up(&server->response_q); | 439 | wake_up(&server->response_q); |
438 | continue; | 440 | continue; |
439 | } else if (length < 4) { | 441 | } else if (length < 4) { |
440 | cFYI(1, | 442 | cFYI(1, ("less than four bytes received (%d bytes)", |
441 | ("Frame under four bytes received (%d bytes long)", | ||
442 | length)); | 443 | length)); |
443 | cifs_reconnect(server); | 444 | pdu_length -= length; |
444 | csocket = server->ssocket; | 445 | msleep(1); |
445 | wake_up(&server->response_q); | 446 | goto incomplete_rcv; |
446 | continue; | ||
447 | } | 447 | } |
448 | 448 | ||
449 | /* The right amount was read from socket - 4 bytes */ | 449 | /* The right amount was read from socket - 4 bytes */ |
@@ -504,7 +504,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
504 | 504 | ||
505 | /* else we have an SMB response */ | 505 | /* else we have an SMB response */ |
506 | if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) || | 506 | if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) || |
507 | (pdu_length < sizeof (struct smb_hdr) - 1 - 4)) { | 507 | (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) { |
508 | cERROR(1, ("Invalid size SMB length %d pdu_length %d", | 508 | cERROR(1, ("Invalid size SMB length %d pdu_length %d", |
509 | length, pdu_length+4)); | 509 | length, pdu_length+4)); |
510 | cifs_reconnect(server); | 510 | cifs_reconnect(server); |
@@ -528,7 +528,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
528 | total_read += length) { | 528 | total_read += length) { |
529 | length = kernel_recvmsg(csocket, &smb_msg, &iov, 1, | 529 | length = kernel_recvmsg(csocket, &smb_msg, &iov, 1, |
530 | pdu_length - total_read, 0); | 530 | pdu_length - total_read, 0); |
531 | if ( kthread_should_stop() || | 531 | if (kthread_should_stop() || |
532 | (length == -EINTR)) { | 532 | (length == -EINTR)) { |
533 | /* then will exit */ | 533 | /* then will exit */ |
534 | reconnect = 2; | 534 | reconnect = 2; |
@@ -546,6 +546,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) | |||
546 | allowing socket to clear and app | 546 | allowing socket to clear and app |
547 | threads to set tcpStatus | 547 | threads to set tcpStatus |
548 | CifsNeedReconnect if server hung*/ | 548 | CifsNeedReconnect if server hung*/ |
549 | length = 0; | ||
549 | continue; | 550 | continue; |
550 | } else if (length <= 0) { | 551 | } else if (length <= 0) { |
551 | cERROR(1, ("Received no data, expecting %d", | 552 | cERROR(1, ("Received no data, expecting %d", |
@@ -631,9 +632,9 @@ multi_t2_fnd: | |||
631 | /* Was previous buf put in mpx struct for multi-rsp? */ | 632 | /* Was previous buf put in mpx struct for multi-rsp? */ |
632 | if (!isMultiRsp) { | 633 | if (!isMultiRsp) { |
633 | /* smb buffer will be freed by user thread */ | 634 | /* smb buffer will be freed by user thread */ |
634 | if (isLargeBuf) { | 635 | if (isLargeBuf) |
635 | bigbuf = NULL; | 636 | bigbuf = NULL; |
636 | } else | 637 | else |
637 | smallbuf = NULL; | 638 | smallbuf = NULL; |
638 | } | 639 | } |
639 | wake_up_process(task_to_wake); | 640 | wake_up_process(task_to_wake); |
@@ -676,9 +677,8 @@ multi_t2_fnd: | |||
676 | server->ssocket = NULL; | 677 | server->ssocket = NULL; |
677 | } | 678 | } |
678 | /* buffer usuallly freed in free_mid - need to free it here on exit */ | 679 | /* buffer usuallly freed in free_mid - need to free it here on exit */ |
679 | if (bigbuf != NULL) | 680 | cifs_buf_release(bigbuf); |
680 | cifs_buf_release(bigbuf); | 681 | if (smallbuf) /* no sense logging a debug message if NULL */ |
681 | if (smallbuf != NULL) | ||
682 | cifs_small_buf_release(smallbuf); | 682 | cifs_small_buf_release(smallbuf); |
683 | 683 | ||
684 | read_lock(&GlobalSMBSeslock); | 684 | read_lock(&GlobalSMBSeslock); |
@@ -702,9 +702,8 @@ multi_t2_fnd: | |||
702 | list_for_each(tmp, &GlobalSMBSessionList) { | 702 | list_for_each(tmp, &GlobalSMBSessionList) { |
703 | ses = list_entry(tmp, struct cifsSesInfo, | 703 | ses = list_entry(tmp, struct cifsSesInfo, |
704 | cifsSessionList); | 704 | cifsSessionList); |
705 | if (ses->server == server) { | 705 | if (ses->server == server) |
706 | ses->status = CifsExiting; | 706 | ses->status = CifsExiting; |
707 | } | ||
708 | } | 707 | } |
709 | 708 | ||
710 | spin_lock(&GlobalMid_Lock); | 709 | spin_lock(&GlobalMid_Lock); |
@@ -714,9 +713,8 @@ multi_t2_fnd: | |||
714 | cFYI(1, ("Clearing Mid 0x%x - waking up ", | 713 | cFYI(1, ("Clearing Mid 0x%x - waking up ", |
715 | mid_entry->mid)); | 714 | mid_entry->mid)); |
716 | task_to_wake = mid_entry->tsk; | 715 | task_to_wake = mid_entry->tsk; |
717 | if (task_to_wake) { | 716 | if (task_to_wake) |
718 | wake_up_process(task_to_wake); | 717 | wake_up_process(task_to_wake); |
719 | } | ||
720 | } | 718 | } |
721 | } | 719 | } |
722 | spin_unlock(&GlobalMid_Lock); | 720 | spin_unlock(&GlobalMid_Lock); |
@@ -749,18 +747,15 @@ multi_t2_fnd: | |||
749 | list_for_each(tmp, &GlobalSMBSessionList) { | 747 | list_for_each(tmp, &GlobalSMBSessionList) { |
750 | ses = list_entry(tmp, struct cifsSesInfo, | 748 | ses = list_entry(tmp, struct cifsSesInfo, |
751 | cifsSessionList); | 749 | cifsSessionList); |
752 | if (ses->server == server) { | 750 | if (ses->server == server) |
753 | ses->server = NULL; | 751 | ses->server = NULL; |
754 | } | ||
755 | } | 752 | } |
756 | write_unlock(&GlobalSMBSeslock); | 753 | write_unlock(&GlobalSMBSeslock); |
757 | 754 | ||
758 | kfree(server); | 755 | kfree(server); |
759 | if (length > 0) { | 756 | if (length > 0) |
760 | mempool_resize(cifs_req_poolp, | 757 | mempool_resize(cifs_req_poolp, length + cifs_min_rcv, |
761 | length + cifs_min_rcv, | 758 | GFP_KERNEL); |
762 | GFP_KERNEL); | ||
763 | } | ||
764 | 759 | ||
765 | return 0; | 760 | return 0; |
766 | } | 761 | } |
@@ -1477,7 +1472,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, | |||
1477 | if (psin_server->sin_port) { /* user overrode default port */ | 1472 | if (psin_server->sin_port) { /* user overrode default port */ |
1478 | rc = (*csocket)->ops->connect(*csocket, | 1473 | rc = (*csocket)->ops->connect(*csocket, |
1479 | (struct sockaddr *) psin_server, | 1474 | (struct sockaddr *) psin_server, |
1480 | sizeof (struct sockaddr_in), 0); | 1475 | sizeof(struct sockaddr_in), 0); |
1481 | if (rc >= 0) | 1476 | if (rc >= 0) |
1482 | connected = 1; | 1477 | connected = 1; |
1483 | } | 1478 | } |
@@ -1493,7 +1488,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, | |||
1493 | 1488 | ||
1494 | rc = (*csocket)->ops->connect(*csocket, | 1489 | rc = (*csocket)->ops->connect(*csocket, |
1495 | (struct sockaddr *) psin_server, | 1490 | (struct sockaddr *) psin_server, |
1496 | sizeof (struct sockaddr_in), 0); | 1491 | sizeof(struct sockaddr_in), 0); |
1497 | if (rc >= 0) | 1492 | if (rc >= 0) |
1498 | connected = 1; | 1493 | connected = 1; |
1499 | } | 1494 | } |
@@ -1502,7 +1497,7 @@ ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket, | |||
1502 | psin_server->sin_port = htons(RFC1001_PORT); | 1497 | psin_server->sin_port = htons(RFC1001_PORT); |
1503 | rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *) | 1498 | rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *) |
1504 | psin_server, | 1499 | psin_server, |
1505 | sizeof (struct sockaddr_in), 0); | 1500 | sizeof(struct sockaddr_in), 0); |
1506 | if (rc >= 0) | 1501 | if (rc >= 0) |
1507 | connected = 1; | 1502 | connected = 1; |
1508 | } | 1503 | } |
@@ -1610,7 +1605,7 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket) | |||
1610 | if (psin_server->sin6_port) { /* user overrode default port */ | 1605 | if (psin_server->sin6_port) { /* user overrode default port */ |
1611 | rc = (*csocket)->ops->connect(*csocket, | 1606 | rc = (*csocket)->ops->connect(*csocket, |
1612 | (struct sockaddr *) psin_server, | 1607 | (struct sockaddr *) psin_server, |
1613 | sizeof (struct sockaddr_in6), 0); | 1608 | sizeof(struct sockaddr_in6), 0); |
1614 | if (rc >= 0) | 1609 | if (rc >= 0) |
1615 | connected = 1; | 1610 | connected = 1; |
1616 | } | 1611 | } |
@@ -1626,7 +1621,7 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket) | |||
1626 | 1621 | ||
1627 | rc = (*csocket)->ops->connect(*csocket, | 1622 | rc = (*csocket)->ops->connect(*csocket, |
1628 | (struct sockaddr *) psin_server, | 1623 | (struct sockaddr *) psin_server, |
1629 | sizeof (struct sockaddr_in6), 0); | 1624 | sizeof(struct sockaddr_in6), 0); |
1630 | if (rc >= 0) | 1625 | if (rc >= 0) |
1631 | connected = 1; | 1626 | connected = 1; |
1632 | } | 1627 | } |
@@ -1634,7 +1629,7 @@ ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket) | |||
1634 | if (!connected) { | 1629 | if (!connected) { |
1635 | psin_server->sin6_port = htons(RFC1001_PORT); | 1630 | psin_server->sin6_port = htons(RFC1001_PORT); |
1636 | rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *) | 1631 | rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *) |
1637 | psin_server, sizeof (struct sockaddr_in6), 0); | 1632 | psin_server, sizeof(struct sockaddr_in6), 0); |
1638 | if (rc >= 0) | 1633 | if (rc >= 0) |
1639 | connected = 1; | 1634 | connected = 1; |
1640 | } | 1635 | } |
@@ -1750,7 +1745,16 @@ void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon, | |||
1750 | cFYI(1, ("very large write cap")); | 1745 | cFYI(1, ("very large write cap")); |
1751 | #endif /* CIFS_DEBUG2 */ | 1746 | #endif /* CIFS_DEBUG2 */ |
1752 | if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) { | 1747 | if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) { |
1753 | cFYI(1, ("setting capabilities failed")); | 1748 | if (vol_info == NULL) { |
1749 | cFYI(1, ("resetting capabilities failed")); | ||
1750 | } else | ||
1751 | cERROR(1, ("Negotiating Unix capabilities " | ||
1752 | "with the server failed. Consider " | ||
1753 | "mounting with the Unix Extensions\n" | ||
1754 | "disabled, if problems are found, " | ||
1755 | "by specifying the nounix mount " | ||
1756 | "option.")); | ||
1757 | |||
1754 | } | 1758 | } |
1755 | } | 1759 | } |
1756 | } | 1760 | } |
@@ -1909,8 +1913,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
1909 | return rc; | 1913 | return rc; |
1910 | } | 1914 | } |
1911 | 1915 | ||
1912 | srvTcp = kmalloc(sizeof (struct TCP_Server_Info), GFP_KERNEL); | 1916 | srvTcp = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL); |
1913 | if (srvTcp == NULL) { | 1917 | if (!srvTcp) { |
1914 | rc = -ENOMEM; | 1918 | rc = -ENOMEM; |
1915 | sock_release(csocket); | 1919 | sock_release(csocket); |
1916 | kfree(volume_info.UNC); | 1920 | kfree(volume_info.UNC); |
@@ -1919,9 +1923,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
1919 | FreeXid(xid); | 1923 | FreeXid(xid); |
1920 | return rc; | 1924 | return rc; |
1921 | } else { | 1925 | } else { |
1922 | memset(srvTcp, 0, sizeof (struct TCP_Server_Info)); | ||
1923 | memcpy(&srvTcp->addr.sockAddr, &sin_server, | 1926 | memcpy(&srvTcp->addr.sockAddr, &sin_server, |
1924 | sizeof (struct sockaddr_in)); | 1927 | sizeof(struct sockaddr_in)); |
1925 | atomic_set(&srvTcp->inFlight, 0); | 1928 | atomic_set(&srvTcp->inFlight, 0); |
1926 | /* BB Add code for ipv6 case too */ | 1929 | /* BB Add code for ipv6 case too */ |
1927 | srvTcp->ssocket = csocket; | 1930 | srvTcp->ssocket = csocket; |
@@ -2173,8 +2176,18 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2173 | if (tsk) | 2176 | if (tsk) |
2174 | kthread_stop(tsk); | 2177 | kthread_stop(tsk); |
2175 | } | 2178 | } |
2176 | } else | 2179 | } else { |
2177 | cFYI(1, ("No session or bad tcon")); | 2180 | cFYI(1, ("No session or bad tcon")); |
2181 | if ((pSesInfo->server) && | ||
2182 | (pSesInfo->server->tsk)) { | ||
2183 | struct task_struct *tsk; | ||
2184 | force_sig(SIGKILL, | ||
2185 | pSesInfo->server->tsk); | ||
2186 | tsk = pSesInfo->server->tsk; | ||
2187 | if (tsk) | ||
2188 | kthread_stop(tsk); | ||
2189 | } | ||
2190 | } | ||
2178 | sesInfoFree(pSesInfo); | 2191 | sesInfoFree(pSesInfo); |
2179 | /* pSesInfo = NULL; */ | 2192 | /* pSesInfo = NULL; */ |
2180 | } | 2193 | } |
@@ -2185,8 +2198,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, | |||
2185 | tcon->ses = pSesInfo; | 2198 | tcon->ses = pSesInfo; |
2186 | 2199 | ||
2187 | /* do not care if following two calls succeed - informational */ | 2200 | /* do not care if following two calls succeed - informational */ |
2188 | CIFSSMBQFSDeviceInfo(xid, tcon); | 2201 | if (!tcon->ipc) { |
2189 | CIFSSMBQFSAttributeInfo(xid, tcon); | 2202 | CIFSSMBQFSDeviceInfo(xid, tcon); |
2203 | CIFSSMBQFSAttributeInfo(xid, tcon); | ||
2204 | } | ||
2190 | 2205 | ||
2191 | /* tell server which Unix caps we support */ | 2206 | /* tell server which Unix caps we support */ |
2192 | if (tcon->ses->capabilities & CAP_UNIX) | 2207 | if (tcon->ses->capabilities & CAP_UNIX) |
@@ -2526,8 +2541,7 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2526 | sesssetup_nomem: /* do not return an error on nomem for the info strings, | 2541 | sesssetup_nomem: /* do not return an error on nomem for the info strings, |
2527 | since that could make reconnection harder, and | 2542 | since that could make reconnection harder, and |
2528 | reconnection might be needed to free memory */ | 2543 | reconnection might be needed to free memory */ |
2529 | if (smb_buffer) | 2544 | cifs_buf_release(smb_buffer); |
2530 | cifs_buf_release(smb_buffer); | ||
2531 | 2545 | ||
2532 | return rc; | 2546 | return rc; |
2533 | } | 2547 | } |
@@ -2547,7 +2561,7 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
2547 | int remaining_words = 0; | 2561 | int remaining_words = 0; |
2548 | int bytes_returned = 0; | 2562 | int bytes_returned = 0; |
2549 | int len; | 2563 | int len; |
2550 | int SecurityBlobLength = sizeof (NEGOTIATE_MESSAGE); | 2564 | int SecurityBlobLength = sizeof(NEGOTIATE_MESSAGE); |
2551 | PNEGOTIATE_MESSAGE SecurityBlob; | 2565 | PNEGOTIATE_MESSAGE SecurityBlob; |
2552 | PCHALLENGE_MESSAGE SecurityBlob2; | 2566 | PCHALLENGE_MESSAGE SecurityBlob2; |
2553 | __u32 negotiate_flags, capabilities; | 2567 | __u32 negotiate_flags, capabilities; |
@@ -2865,15 +2879,14 @@ CIFSNTLMSSPNegotiateSessSetup(unsigned int xid, | |||
2865 | rc = -EIO; | 2879 | rc = -EIO; |
2866 | } | 2880 | } |
2867 | 2881 | ||
2868 | if (smb_buffer) | 2882 | cifs_buf_release(smb_buffer); |
2869 | cifs_buf_release(smb_buffer); | ||
2870 | 2883 | ||
2871 | return rc; | 2884 | return rc; |
2872 | } | 2885 | } |
2873 | static int | 2886 | static int |
2874 | CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, | 2887 | CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, |
2875 | char *ntlm_session_key, int ntlmv2_flag, | 2888 | char *ntlm_session_key, int ntlmv2_flag, |
2876 | const struct nls_table *nls_codepage) | 2889 | const struct nls_table *nls_codepage) |
2877 | { | 2890 | { |
2878 | struct smb_hdr *smb_buffer; | 2891 | struct smb_hdr *smb_buffer; |
2879 | struct smb_hdr *smb_buffer_response; | 2892 | struct smb_hdr *smb_buffer_response; |
@@ -2886,7 +2899,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2886 | int remaining_words = 0; | 2899 | int remaining_words = 0; |
2887 | int bytes_returned = 0; | 2900 | int bytes_returned = 0; |
2888 | int len; | 2901 | int len; |
2889 | int SecurityBlobLength = sizeof (AUTHENTICATE_MESSAGE); | 2902 | int SecurityBlobLength = sizeof(AUTHENTICATE_MESSAGE); |
2890 | PAUTHENTICATE_MESSAGE SecurityBlob; | 2903 | PAUTHENTICATE_MESSAGE SecurityBlob; |
2891 | __u32 negotiate_flags, capabilities; | 2904 | __u32 negotiate_flags, capabilities; |
2892 | __u16 count; | 2905 | __u16 count; |
@@ -2901,8 +2914,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2901 | return -ENOMEM; | 2914 | return -ENOMEM; |
2902 | } | 2915 | } |
2903 | smb_buffer_response = smb_buffer; | 2916 | smb_buffer_response = smb_buffer; |
2904 | pSMB = (SESSION_SETUP_ANDX *) smb_buffer; | 2917 | pSMB = (SESSION_SETUP_ANDX *)smb_buffer; |
2905 | pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response; | 2918 | pSMBr = (SESSION_SETUP_ANDX *)smb_buffer_response; |
2906 | 2919 | ||
2907 | /* send SMBsessionSetup here */ | 2920 | /* send SMBsessionSetup here */ |
2908 | header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX, | 2921 | header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX, |
@@ -2921,7 +2934,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2921 | smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; | 2934 | smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE; |
2922 | 2935 | ||
2923 | capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | | 2936 | capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS | |
2924 | CAP_EXTENDED_SECURITY; | 2937 | CAP_EXTENDED_SECURITY; |
2925 | if (ses->capabilities & CAP_UNICODE) { | 2938 | if (ses->capabilities & CAP_UNICODE) { |
2926 | smb_buffer->Flags2 |= SMBFLG2_UNICODE; | 2939 | smb_buffer->Flags2 |= SMBFLG2_UNICODE; |
2927 | capabilities |= CAP_UNICODE; | 2940 | capabilities |= CAP_UNICODE; |
@@ -2936,15 +2949,14 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2936 | } | 2949 | } |
2937 | pSMB->req.Capabilities = cpu_to_le32(capabilities); | 2950 | pSMB->req.Capabilities = cpu_to_le32(capabilities); |
2938 | 2951 | ||
2939 | bcc_ptr = (char *) &pSMB->req.SecurityBlob; | 2952 | bcc_ptr = (char *)&pSMB->req.SecurityBlob; |
2940 | SecurityBlob = (PAUTHENTICATE_MESSAGE) bcc_ptr; | 2953 | SecurityBlob = (PAUTHENTICATE_MESSAGE)bcc_ptr; |
2941 | strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8); | 2954 | strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8); |
2942 | SecurityBlob->MessageType = NtLmAuthenticate; | 2955 | SecurityBlob->MessageType = NtLmAuthenticate; |
2943 | bcc_ptr += SecurityBlobLength; | 2956 | bcc_ptr += SecurityBlobLength; |
2944 | negotiate_flags = | 2957 | negotiate_flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET | |
2945 | NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET | | 2958 | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO | |
2946 | NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO | | 2959 | 0x80000000 | NTLMSSP_NEGOTIATE_128; |
2947 | 0x80000000 | NTLMSSP_NEGOTIATE_128; | ||
2948 | if (sign_CIFS_PDUs) | 2960 | if (sign_CIFS_PDUs) |
2949 | negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN; | 2961 | negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN; |
2950 | if (ntlmv2_flag) | 2962 | if (ntlmv2_flag) |
@@ -2979,36 +2991,32 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
2979 | SecurityBlob->DomainName.Length = 0; | 2991 | SecurityBlob->DomainName.Length = 0; |
2980 | SecurityBlob->DomainName.MaximumLength = 0; | 2992 | SecurityBlob->DomainName.MaximumLength = 0; |
2981 | } else { | 2993 | } else { |
2982 | __u16 len = | 2994 | __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64, |
2983 | cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64, | ||
2984 | nls_codepage); | 2995 | nls_codepage); |
2985 | len *= 2; | 2996 | ln *= 2; |
2986 | SecurityBlob->DomainName.MaximumLength = | 2997 | SecurityBlob->DomainName.MaximumLength = |
2987 | cpu_to_le16(len); | 2998 | cpu_to_le16(ln); |
2988 | SecurityBlob->DomainName.Buffer = | 2999 | SecurityBlob->DomainName.Buffer = |
2989 | cpu_to_le32(SecurityBlobLength); | 3000 | cpu_to_le32(SecurityBlobLength); |
2990 | bcc_ptr += len; | 3001 | bcc_ptr += ln; |
2991 | SecurityBlobLength += len; | 3002 | SecurityBlobLength += ln; |
2992 | SecurityBlob->DomainName.Length = | 3003 | SecurityBlob->DomainName.Length = cpu_to_le16(ln); |
2993 | cpu_to_le16(len); | ||
2994 | } | 3004 | } |
2995 | if (user == NULL) { | 3005 | if (user == NULL) { |
2996 | SecurityBlob->UserName.Buffer = 0; | 3006 | SecurityBlob->UserName.Buffer = 0; |
2997 | SecurityBlob->UserName.Length = 0; | 3007 | SecurityBlob->UserName.Length = 0; |
2998 | SecurityBlob->UserName.MaximumLength = 0; | 3008 | SecurityBlob->UserName.MaximumLength = 0; |
2999 | } else { | 3009 | } else { |
3000 | __u16 len = | 3010 | __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, user, 64, |
3001 | cifs_strtoUCS((__le16 *) bcc_ptr, user, 64, | ||
3002 | nls_codepage); | 3011 | nls_codepage); |
3003 | len *= 2; | 3012 | ln *= 2; |
3004 | SecurityBlob->UserName.MaximumLength = | 3013 | SecurityBlob->UserName.MaximumLength = |
3005 | cpu_to_le16(len); | 3014 | cpu_to_le16(ln); |
3006 | SecurityBlob->UserName.Buffer = | 3015 | SecurityBlob->UserName.Buffer = |
3007 | cpu_to_le32(SecurityBlobLength); | 3016 | cpu_to_le32(SecurityBlobLength); |
3008 | bcc_ptr += len; | 3017 | bcc_ptr += ln; |
3009 | SecurityBlobLength += len; | 3018 | SecurityBlobLength += ln; |
3010 | SecurityBlob->UserName.Length = | 3019 | SecurityBlob->UserName.Length = cpu_to_le16(ln); |
3011 | cpu_to_le16(len); | ||
3012 | } | 3020 | } |
3013 | 3021 | ||
3014 | /* SecurityBlob->WorkstationName.Length = | 3022 | /* SecurityBlob->WorkstationName.Length = |
@@ -3052,33 +3060,32 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
3052 | SecurityBlob->DomainName.Length = 0; | 3060 | SecurityBlob->DomainName.Length = 0; |
3053 | SecurityBlob->DomainName.MaximumLength = 0; | 3061 | SecurityBlob->DomainName.MaximumLength = 0; |
3054 | } else { | 3062 | } else { |
3055 | __u16 len; | 3063 | __u16 ln; |
3056 | negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED; | 3064 | negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED; |
3057 | strncpy(bcc_ptr, domain, 63); | 3065 | strncpy(bcc_ptr, domain, 63); |
3058 | len = strnlen(domain, 64); | 3066 | ln = strnlen(domain, 64); |
3059 | SecurityBlob->DomainName.MaximumLength = | 3067 | SecurityBlob->DomainName.MaximumLength = |
3060 | cpu_to_le16(len); | 3068 | cpu_to_le16(ln); |
3061 | SecurityBlob->DomainName.Buffer = | 3069 | SecurityBlob->DomainName.Buffer = |
3062 | cpu_to_le32(SecurityBlobLength); | 3070 | cpu_to_le32(SecurityBlobLength); |
3063 | bcc_ptr += len; | 3071 | bcc_ptr += ln; |
3064 | SecurityBlobLength += len; | 3072 | SecurityBlobLength += ln; |
3065 | SecurityBlob->DomainName.Length = cpu_to_le16(len); | 3073 | SecurityBlob->DomainName.Length = cpu_to_le16(ln); |
3066 | } | 3074 | } |
3067 | if (user == NULL) { | 3075 | if (user == NULL) { |
3068 | SecurityBlob->UserName.Buffer = 0; | 3076 | SecurityBlob->UserName.Buffer = 0; |
3069 | SecurityBlob->UserName.Length = 0; | 3077 | SecurityBlob->UserName.Length = 0; |
3070 | SecurityBlob->UserName.MaximumLength = 0; | 3078 | SecurityBlob->UserName.MaximumLength = 0; |
3071 | } else { | 3079 | } else { |
3072 | __u16 len; | 3080 | __u16 ln; |
3073 | strncpy(bcc_ptr, user, 63); | 3081 | strncpy(bcc_ptr, user, 63); |
3074 | len = strnlen(user, 64); | 3082 | ln = strnlen(user, 64); |
3075 | SecurityBlob->UserName.MaximumLength = | 3083 | SecurityBlob->UserName.MaximumLength = cpu_to_le16(ln); |
3076 | cpu_to_le16(len); | ||
3077 | SecurityBlob->UserName.Buffer = | 3084 | SecurityBlob->UserName.Buffer = |
3078 | cpu_to_le32(SecurityBlobLength); | 3085 | cpu_to_le32(SecurityBlobLength); |
3079 | bcc_ptr += len; | 3086 | bcc_ptr += ln; |
3080 | SecurityBlobLength += len; | 3087 | SecurityBlobLength += ln; |
3081 | SecurityBlob->UserName.Length = cpu_to_le16(len); | 3088 | SecurityBlob->UserName.Length = cpu_to_le16(ln); |
3082 | } | 3089 | } |
3083 | /* BB fill in our workstation name if known BB */ | 3090 | /* BB fill in our workstation name if known BB */ |
3084 | 3091 | ||
@@ -3100,12 +3107,11 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
3100 | rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, | 3107 | rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, |
3101 | &bytes_returned, 1); | 3108 | &bytes_returned, 1); |
3102 | if (rc) { | 3109 | if (rc) { |
3103 | /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */ | 3110 | /* rc = map_smb_to_linux_error(smb_buffer_response) done in SendReceive now */ |
3104 | } else if ((smb_buffer_response->WordCount == 3) | 3111 | } else if ((smb_buffer_response->WordCount == 3) || |
3105 | || (smb_buffer_response->WordCount == 4)) { | 3112 | (smb_buffer_response->WordCount == 4)) { |
3106 | __u16 action = le16_to_cpu(pSMBr->resp.Action); | 3113 | __u16 action = le16_to_cpu(pSMBr->resp.Action); |
3107 | __u16 blob_len = | 3114 | __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength); |
3108 | le16_to_cpu(pSMBr->resp.SecurityBlobLength); | ||
3109 | if (action & GUEST_LOGIN) | 3115 | if (action & GUEST_LOGIN) |
3110 | cFYI(1, (" Guest login")); /* BB Should we set anything | 3116 | cFYI(1, (" Guest login")); /* BB Should we set anything |
3111 | in SesInfo struct ? */ | 3117 | in SesInfo struct ? */ |
@@ -3145,8 +3151,8 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
3145 | } else { | 3151 | } else { |
3146 | remaining_words = BCC(smb_buffer_response) / 2; | 3152 | remaining_words = BCC(smb_buffer_response) / 2; |
3147 | } | 3153 | } |
3148 | len = | 3154 | len = UniStrnlen((wchar_t *) bcc_ptr, |
3149 | UniStrnlen((wchar_t *) bcc_ptr,remaining_words - 1); | 3155 | remaining_words - 1); |
3150 | /* We look for obvious messed up bcc or strings in response so we do not go off | 3156 | /* We look for obvious messed up bcc or strings in response so we do not go off |
3151 | the end since (at least) WIN2K and Windows XP have a major bug in not null | 3157 | the end since (at least) WIN2K and Windows XP have a major bug in not null |
3152 | terminating last Unicode string in response */ | 3158 | terminating last Unicode string in response */ |
@@ -3230,7 +3236,7 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
3230 | <= BCC(smb_buffer_response)) { | 3236 | <= BCC(smb_buffer_response)) { |
3231 | if (ses->serverOS) | 3237 | if (ses->serverOS) |
3232 | kfree(ses->serverOS); | 3238 | kfree(ses->serverOS); |
3233 | ses->serverOS = kzalloc(len + 1,GFP_KERNEL); | 3239 | ses->serverOS = kzalloc(len + 1, GFP_KERNEL); |
3234 | strncpy(ses->serverOS,bcc_ptr, len); | 3240 | strncpy(ses->serverOS,bcc_ptr, len); |
3235 | 3241 | ||
3236 | bcc_ptr += len; | 3242 | bcc_ptr += len; |
@@ -3259,28 +3265,24 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses, | |||
3259 | bcc_ptr[0] = 0; | 3265 | bcc_ptr[0] = 0; |
3260 | bcc_ptr++; | 3266 | bcc_ptr++; |
3261 | } else | 3267 | } else |
3262 | cFYI(1, | 3268 | cFYI(1, ("field of length %d " |
3263 | ("field of length %d " | ||
3264 | "extends beyond end of smb ", | 3269 | "extends beyond end of smb ", |
3265 | len)); | 3270 | len)); |
3266 | } | 3271 | } |
3267 | } else { | 3272 | } else { |
3268 | cERROR(1, | 3273 | cERROR(1, ("Security Blob extends beyond end " |
3269 | (" Security Blob extends beyond end " | ||
3270 | "of SMB")); | 3274 | "of SMB")); |
3271 | } | 3275 | } |
3272 | } else { | 3276 | } else { |
3273 | cERROR(1, ("No session structure passed in.")); | 3277 | cERROR(1, ("No session structure passed in.")); |
3274 | } | 3278 | } |
3275 | } else { | 3279 | } else { |
3276 | cERROR(1, | 3280 | cERROR(1, ("Invalid Word count %d: ", |
3277 | (" Invalid Word count %d: ", | ||
3278 | smb_buffer_response->WordCount)); | 3281 | smb_buffer_response->WordCount)); |
3279 | rc = -EIO; | 3282 | rc = -EIO; |
3280 | } | 3283 | } |
3281 | 3284 | ||
3282 | if (smb_buffer) | 3285 | cifs_buf_release(smb_buffer); |
3283 | cifs_buf_release(smb_buffer); | ||
3284 | 3286 | ||
3285 | return rc; | 3287 | return rc; |
3286 | } | 3288 | } |
@@ -3389,6 +3391,18 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, | |||
3389 | bcc_ptr = pByteArea(smb_buffer_response); | 3391 | bcc_ptr = pByteArea(smb_buffer_response); |
3390 | length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2); | 3392 | length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2); |
3391 | /* skip service field (NB: this field is always ASCII) */ | 3393 | /* skip service field (NB: this field is always ASCII) */ |
3394 | if (length == 3) { | ||
3395 | if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') && | ||
3396 | (bcc_ptr[2] == 'C')) { | ||
3397 | cFYI(1, ("IPC connection")); | ||
3398 | tcon->ipc = 1; | ||
3399 | } | ||
3400 | } else if (length == 2) { | ||
3401 | if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) { | ||
3402 | /* the most common case */ | ||
3403 | cFYI(1, ("disk share connection")); | ||
3404 | } | ||
3405 | } | ||
3392 | bcc_ptr += length + 1; | 3406 | bcc_ptr += length + 1; |
3393 | strncpy(tcon->treeName, tree, MAX_TREE_SIZE); | 3407 | strncpy(tcon->treeName, tree, MAX_TREE_SIZE); |
3394 | if (smb_buffer->Flags2 & SMBFLG2_UNICODE) { | 3408 | if (smb_buffer->Flags2 & SMBFLG2_UNICODE) { |
@@ -3399,9 +3413,11 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, | |||
3399 | kfree(tcon->nativeFileSystem); | 3413 | kfree(tcon->nativeFileSystem); |
3400 | tcon->nativeFileSystem = | 3414 | tcon->nativeFileSystem = |
3401 | kzalloc(length + 2, GFP_KERNEL); | 3415 | kzalloc(length + 2, GFP_KERNEL); |
3402 | cifs_strfromUCS_le(tcon->nativeFileSystem, | 3416 | if (tcon->nativeFileSystem) |
3403 | (__le16 *) bcc_ptr, | 3417 | cifs_strfromUCS_le( |
3404 | length, nls_codepage); | 3418 | tcon->nativeFileSystem, |
3419 | (__le16 *) bcc_ptr, | ||
3420 | length, nls_codepage); | ||
3405 | bcc_ptr += 2 * length; | 3421 | bcc_ptr += 2 * length; |
3406 | bcc_ptr[0] = 0; /* null terminate the string */ | 3422 | bcc_ptr[0] = 0; /* null terminate the string */ |
3407 | bcc_ptr[1] = 0; | 3423 | bcc_ptr[1] = 0; |
@@ -3416,8 +3432,9 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, | |||
3416 | kfree(tcon->nativeFileSystem); | 3432 | kfree(tcon->nativeFileSystem); |
3417 | tcon->nativeFileSystem = | 3433 | tcon->nativeFileSystem = |
3418 | kzalloc(length + 1, GFP_KERNEL); | 3434 | kzalloc(length + 1, GFP_KERNEL); |
3419 | strncpy(tcon->nativeFileSystem, bcc_ptr, | 3435 | if (tcon->nativeFileSystem) |
3420 | length); | 3436 | strncpy(tcon->nativeFileSystem, bcc_ptr, |
3437 | length); | ||
3421 | } | 3438 | } |
3422 | /* else do not bother copying these information fields*/ | 3439 | /* else do not bother copying these information fields*/ |
3423 | } | 3440 | } |
@@ -3433,8 +3450,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, | |||
3433 | ses->ipc_tid = smb_buffer_response->Tid; | 3450 | ses->ipc_tid = smb_buffer_response->Tid; |
3434 | } | 3451 | } |
3435 | 3452 | ||
3436 | if (smb_buffer) | 3453 | cifs_buf_release(smb_buffer); |
3437 | cifs_buf_release(smb_buffer); | ||
3438 | return rc; | 3454 | return rc; |
3439 | } | 3455 | } |
3440 | 3456 | ||
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 4830acc86d74..793404b10925 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * vfs operations that deal with dentries | 4 | * vfs operations that deal with dentries |
5 | * | 5 | * |
6 | * Copyright (C) International Business Machines Corp., 2002,2005 | 6 | * Copyright (C) International Business Machines Corp., 2002,2007 |
7 | * Author(s): Steve French (sfrench@us.ibm.com) | 7 | * Author(s): Steve French (sfrench@us.ibm.com) |
8 | * | 8 | * |
9 | * This library is free software; you can redistribute it and/or modify | 9 | * This library is free software; you can redistribute it and/or modify |
@@ -269,7 +269,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
269 | CIFSSMBClose(xid, pTcon, fileHandle); | 269 | CIFSSMBClose(xid, pTcon, fileHandle); |
270 | } else if (newinode) { | 270 | } else if (newinode) { |
271 | pCifsFile = | 271 | pCifsFile = |
272 | kzalloc(sizeof (struct cifsFileInfo), GFP_KERNEL); | 272 | kzalloc(sizeof(struct cifsFileInfo), GFP_KERNEL); |
273 | 273 | ||
274 | if (pCifsFile == NULL) | 274 | if (pCifsFile == NULL) |
275 | goto cifs_create_out; | 275 | goto cifs_create_out; |
@@ -397,7 +397,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, | |||
397 | /* BB Do not bother to decode buf since no | 397 | /* BB Do not bother to decode buf since no |
398 | local inode yet to put timestamps in, | 398 | local inode yet to put timestamps in, |
399 | but we can reuse it safely */ | 399 | but we can reuse it safely */ |
400 | int bytes_written; | 400 | unsigned int bytes_written; |
401 | struct win_dev *pdev; | 401 | struct win_dev *pdev; |
402 | pdev = (struct win_dev *)buf; | 402 | pdev = (struct win_dev *)buf; |
403 | if (S_ISCHR(mode)) { | 403 | if (S_ISCHR(mode)) { |
@@ -450,8 +450,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, | |||
450 | 450 | ||
451 | xid = GetXid(); | 451 | xid = GetXid(); |
452 | 452 | ||
453 | cFYI(1, | 453 | cFYI(1, (" parent inode = 0x%p name is: %s and dentry = 0x%p", |
454 | (" parent inode = 0x%p name is: %s and dentry = 0x%p", | ||
455 | parent_dir_inode, direntry->d_name.name, direntry)); | 454 | parent_dir_inode, direntry->d_name.name, direntry)); |
456 | 455 | ||
457 | /* check whether path exists */ | 456 | /* check whether path exists */ |
diff --git a/fs/cifs/export.c b/fs/cifs/export.c index 893fd0aebff8..d614b91caeca 100644 --- a/fs/cifs/export.c +++ b/fs/cifs/export.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/exportfs.h> | 43 | #include <linux/exportfs.h> |
44 | #include "cifsglob.h" | 44 | #include "cifsglob.h" |
45 | #include "cifs_debug.h" | 45 | #include "cifs_debug.h" |
46 | #include "cifsfs.h" | ||
46 | 47 | ||
47 | #ifdef CONFIG_CIFS_EXPERIMENTAL | 48 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
48 | static struct dentry *cifs_get_parent(struct dentry *dentry) | 49 | static struct dentry *cifs_get_parent(struct dentry *dentry) |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 894b1f7b299d..1e7e4c06d9e3 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -467,7 +467,7 @@ reopen_error_exit: | |||
467 | int cifs_close(struct inode *inode, struct file *file) | 467 | int cifs_close(struct inode *inode, struct file *file) |
468 | { | 468 | { |
469 | int rc = 0; | 469 | int rc = 0; |
470 | int xid; | 470 | int xid, timeout; |
471 | struct cifs_sb_info *cifs_sb; | 471 | struct cifs_sb_info *cifs_sb; |
472 | struct cifsTconInfo *pTcon; | 472 | struct cifsTconInfo *pTcon; |
473 | struct cifsFileInfo *pSMBFile = | 473 | struct cifsFileInfo *pSMBFile = |
@@ -485,9 +485,9 @@ int cifs_close(struct inode *inode, struct file *file) | |||
485 | /* no sense reconnecting to close a file that is | 485 | /* no sense reconnecting to close a file that is |
486 | already closed */ | 486 | already closed */ |
487 | if (pTcon->tidStatus != CifsNeedReconnect) { | 487 | if (pTcon->tidStatus != CifsNeedReconnect) { |
488 | int timeout = 2; | 488 | timeout = 2; |
489 | while ((atomic_read(&pSMBFile->wrtPending) != 0) | 489 | while ((atomic_read(&pSMBFile->wrtPending) != 0) |
490 | && (timeout < 1000) ) { | 490 | && (timeout <= 2048)) { |
491 | /* Give write a better chance to get to | 491 | /* Give write a better chance to get to |
492 | server ahead of the close. We do not | 492 | server ahead of the close. We do not |
493 | want to add a wait_q here as it would | 493 | want to add a wait_q here as it would |
@@ -522,12 +522,30 @@ int cifs_close(struct inode *inode, struct file *file) | |||
522 | list_del(&pSMBFile->flist); | 522 | list_del(&pSMBFile->flist); |
523 | list_del(&pSMBFile->tlist); | 523 | list_del(&pSMBFile->tlist); |
524 | write_unlock(&GlobalSMBSeslock); | 524 | write_unlock(&GlobalSMBSeslock); |
525 | timeout = 10; | ||
526 | /* We waited above to give the SMBWrite a chance to issue | ||
527 | on the wire (so we do not get SMBWrite returning EBADF | ||
528 | if writepages is racing with close. Note that writepages | ||
529 | does not specify a file handle, so it is possible for a file | ||
530 | to be opened twice, and the application close the "wrong" | ||
531 | file handle - in these cases we delay long enough to allow | ||
532 | the SMBWrite to get on the wire before the SMB Close. | ||
533 | We allow total wait here over 45 seconds, more than | ||
534 | oplock break time, and more than enough to allow any write | ||
535 | to complete on the server, or to time out on the client */ | ||
536 | while ((atomic_read(&pSMBFile->wrtPending) != 0) | ||
537 | && (timeout <= 50000)) { | ||
538 | cERROR(1, ("writes pending, delay free of handle")); | ||
539 | msleep(timeout); | ||
540 | timeout *= 8; | ||
541 | } | ||
525 | kfree(pSMBFile->search_resume_name); | 542 | kfree(pSMBFile->search_resume_name); |
526 | kfree(file->private_data); | 543 | kfree(file->private_data); |
527 | file->private_data = NULL; | 544 | file->private_data = NULL; |
528 | } else | 545 | } else |
529 | rc = -EBADF; | 546 | rc = -EBADF; |
530 | 547 | ||
548 | read_lock(&GlobalSMBSeslock); | ||
531 | if (list_empty(&(CIFS_I(inode)->openFileList))) { | 549 | if (list_empty(&(CIFS_I(inode)->openFileList))) { |
532 | cFYI(1, ("closing last open instance for inode %p", inode)); | 550 | cFYI(1, ("closing last open instance for inode %p", inode)); |
533 | /* if the file is not open we do not know if we can cache info | 551 | /* if the file is not open we do not know if we can cache info |
@@ -535,6 +553,7 @@ int cifs_close(struct inode *inode, struct file *file) | |||
535 | CIFS_I(inode)->clientCanCacheRead = FALSE; | 553 | CIFS_I(inode)->clientCanCacheRead = FALSE; |
536 | CIFS_I(inode)->clientCanCacheAll = FALSE; | 554 | CIFS_I(inode)->clientCanCacheAll = FALSE; |
537 | } | 555 | } |
556 | read_unlock(&GlobalSMBSeslock); | ||
538 | if ((rc == 0) && CIFS_I(inode)->write_behind_rc) | 557 | if ((rc == 0) && CIFS_I(inode)->write_behind_rc) |
539 | rc = CIFS_I(inode)->write_behind_rc; | 558 | rc = CIFS_I(inode)->write_behind_rc; |
540 | FreeXid(xid); | 559 | FreeXid(xid); |
@@ -767,7 +786,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) | |||
767 | mutex_lock(&fid->lock_mutex); | 786 | mutex_lock(&fid->lock_mutex); |
768 | list_for_each_entry_safe(li, tmp, &fid->llist, llist) { | 787 | list_for_each_entry_safe(li, tmp, &fid->llist, llist) { |
769 | if (pfLock->fl_start <= li->offset && | 788 | if (pfLock->fl_start <= li->offset && |
770 | length >= li->length) { | 789 | (pfLock->fl_start + length) >= |
790 | (li->offset + li->length)) { | ||
771 | stored_rc = CIFSSMBLock(xid, pTcon, | 791 | stored_rc = CIFSSMBLock(xid, pTcon, |
772 | netfid, | 792 | netfid, |
773 | li->length, li->offset, | 793 | li->length, li->offset, |
@@ -1022,6 +1042,7 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) | |||
1022 | } | 1042 | } |
1023 | 1043 | ||
1024 | read_lock(&GlobalSMBSeslock); | 1044 | read_lock(&GlobalSMBSeslock); |
1045 | refind_writable: | ||
1025 | list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { | 1046 | list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { |
1026 | if (open_file->closePend) | 1047 | if (open_file->closePend) |
1027 | continue; | 1048 | continue; |
@@ -1029,24 +1050,49 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) | |||
1029 | ((open_file->pfile->f_flags & O_RDWR) || | 1050 | ((open_file->pfile->f_flags & O_RDWR) || |
1030 | (open_file->pfile->f_flags & O_WRONLY))) { | 1051 | (open_file->pfile->f_flags & O_WRONLY))) { |
1031 | atomic_inc(&open_file->wrtPending); | 1052 | atomic_inc(&open_file->wrtPending); |
1053 | |||
1054 | if (!open_file->invalidHandle) { | ||
1055 | /* found a good writable file */ | ||
1056 | read_unlock(&GlobalSMBSeslock); | ||
1057 | return open_file; | ||
1058 | } | ||
1059 | |||
1032 | read_unlock(&GlobalSMBSeslock); | 1060 | read_unlock(&GlobalSMBSeslock); |
1033 | if ((open_file->invalidHandle) && | 1061 | /* Had to unlock since following call can block */ |
1034 | (!open_file->closePend) /* BB fixme -since the second clause can not be true remove it BB */) { | 1062 | rc = cifs_reopen_file(open_file->pfile, FALSE); |
1035 | rc = cifs_reopen_file(open_file->pfile, FALSE); | 1063 | if (!rc) { |
1036 | /* if it fails, try another handle - might be */ | 1064 | if (!open_file->closePend) |
1037 | /* dangerous to hold up writepages with retry */ | 1065 | return open_file; |
1038 | if (rc) { | 1066 | else { /* start over in case this was deleted */ |
1039 | cFYI(1, | 1067 | /* since the list could be modified */ |
1040 | ("failed on reopen file in wp")); | ||
1041 | read_lock(&GlobalSMBSeslock); | 1068 | read_lock(&GlobalSMBSeslock); |
1042 | /* can not use this handle, no write | 1069 | atomic_dec(&open_file->wrtPending); |
1043 | pending on this one after all */ | 1070 | goto refind_writable; |
1044 | atomic_dec | ||
1045 | (&open_file->wrtPending); | ||
1046 | continue; | ||
1047 | } | 1071 | } |
1048 | } | 1072 | } |
1049 | return open_file; | 1073 | |
1074 | /* if it fails, try another handle if possible - | ||
1075 | (we can not do this if closePending since | ||
1076 | loop could be modified - in which case we | ||
1077 | have to start at the beginning of the list | ||
1078 | again. Note that it would be bad | ||
1079 | to hold up writepages here (rather than | ||
1080 | in caller) with continuous retries */ | ||
1081 | cFYI(1, ("wp failed on reopen file")); | ||
1082 | read_lock(&GlobalSMBSeslock); | ||
1083 | /* can not use this handle, no write | ||
1084 | pending on this one after all */ | ||
1085 | atomic_dec(&open_file->wrtPending); | ||
1086 | |||
1087 | if (open_file->closePend) /* list could have changed */ | ||
1088 | goto refind_writable; | ||
1089 | /* else we simply continue to the next entry. Thus | ||
1090 | we do not loop on reopen errors. If we | ||
1091 | can not reopen the file, for example if we | ||
1092 | reconnected to a server with another client | ||
1093 | racing to delete or lock the file we would not | ||
1094 | make progress if we restarted before the beginning | ||
1095 | of the loop here. */ | ||
1050 | } | 1096 | } |
1051 | } | 1097 | } |
1052 | read_unlock(&GlobalSMBSeslock); | 1098 | read_unlock(&GlobalSMBSeslock); |
@@ -1709,7 +1755,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1709 | struct page *page; | 1755 | struct page *page; |
1710 | struct cifs_sb_info *cifs_sb; | 1756 | struct cifs_sb_info *cifs_sb; |
1711 | struct cifsTconInfo *pTcon; | 1757 | struct cifsTconInfo *pTcon; |
1712 | int bytes_read = 0; | 1758 | unsigned int bytes_read = 0; |
1713 | unsigned int read_size, i; | 1759 | unsigned int read_size, i; |
1714 | char *smb_read_data = NULL; | 1760 | char *smb_read_data = NULL; |
1715 | struct smb_com_read_rsp *pSMBr; | 1761 | struct smb_com_read_rsp *pSMBr; |
@@ -1803,7 +1849,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping, | |||
1803 | 1849 | ||
1804 | i += bytes_read >> PAGE_CACHE_SHIFT; | 1850 | i += bytes_read >> PAGE_CACHE_SHIFT; |
1805 | cifs_stats_bytes_read(pTcon, bytes_read); | 1851 | cifs_stats_bytes_read(pTcon, bytes_read); |
1806 | if ((int)(bytes_read & PAGE_CACHE_MASK) != bytes_read) { | 1852 | if ((bytes_read & PAGE_CACHE_MASK) != bytes_read) { |
1807 | i++; /* account for partial page */ | 1853 | i++; /* account for partial page */ |
1808 | 1854 | ||
1809 | /* server copy of file can have smaller size | 1855 | /* server copy of file can have smaller size |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 279f3c5e0ce3..5e8b388be3b6 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -115,7 +115,7 @@ int cifs_get_inode_info_unix(struct inode **pinode, | |||
115 | inode->i_mode = le64_to_cpu(findData.Permissions); | 115 | inode->i_mode = le64_to_cpu(findData.Permissions); |
116 | /* since we set the inode type below we need to mask off | 116 | /* since we set the inode type below we need to mask off |
117 | to avoid strange results if bits set above */ | 117 | to avoid strange results if bits set above */ |
118 | inode->i_mode &= ~S_IFMT; | 118 | inode->i_mode &= ~S_IFMT; |
119 | if (type == UNIX_FILE) { | 119 | if (type == UNIX_FILE) { |
120 | inode->i_mode |= S_IFREG; | 120 | inode->i_mode |= S_IFREG; |
121 | } else if (type == UNIX_SYMLINK) { | 121 | } else if (type == UNIX_SYMLINK) { |
@@ -575,19 +575,33 @@ int cifs_get_inode_info(struct inode **pinode, | |||
575 | return rc; | 575 | return rc; |
576 | } | 576 | } |
577 | 577 | ||
578 | static const struct inode_operations cifs_ipc_inode_ops = { | ||
579 | .lookup = cifs_lookup, | ||
580 | }; | ||
581 | |||
578 | /* gets root inode */ | 582 | /* gets root inode */ |
579 | void cifs_read_inode(struct inode *inode) | 583 | void cifs_read_inode(struct inode *inode) |
580 | { | 584 | { |
581 | int xid; | 585 | int xid, rc; |
582 | struct cifs_sb_info *cifs_sb; | 586 | struct cifs_sb_info *cifs_sb; |
583 | 587 | ||
584 | cifs_sb = CIFS_SB(inode->i_sb); | 588 | cifs_sb = CIFS_SB(inode->i_sb); |
585 | xid = GetXid(); | 589 | xid = GetXid(); |
586 | 590 | ||
587 | if (cifs_sb->tcon->unix_ext) | 591 | if (cifs_sb->tcon->unix_ext) |
588 | cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid); | 592 | rc = cifs_get_inode_info_unix(&inode, "", inode->i_sb, xid); |
589 | else | 593 | else |
590 | cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid); | 594 | rc = cifs_get_inode_info(&inode, "", NULL, inode->i_sb, xid); |
595 | if (rc && cifs_sb->tcon->ipc) { | ||
596 | cFYI(1, ("ipc connection - fake read inode")); | ||
597 | inode->i_mode |= S_IFDIR; | ||
598 | inode->i_nlink = 2; | ||
599 | inode->i_op = &cifs_ipc_inode_ops; | ||
600 | inode->i_fop = &simple_dir_operations; | ||
601 | inode->i_uid = cifs_sb->mnt_uid; | ||
602 | inode->i_gid = cifs_sb->mnt_gid; | ||
603 | } | ||
604 | |||
591 | /* can not call macro FreeXid here since in a void func */ | 605 | /* can not call macro FreeXid here since in a void func */ |
592 | _FreeXid(xid); | 606 | _FreeXid(xid); |
593 | } | 607 | } |
@@ -919,18 +933,25 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) | |||
919 | goto mkdir_out; | 933 | goto mkdir_out; |
920 | } | 934 | } |
921 | 935 | ||
936 | mode &= ~current->fs->umask; | ||
922 | rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT, | 937 | rc = CIFSPOSIXCreate(xid, pTcon, SMB_O_DIRECTORY | SMB_O_CREAT, |
923 | mode, NULL /* netfid */, pInfo, &oplock, | 938 | mode, NULL /* netfid */, pInfo, &oplock, |
924 | full_path, cifs_sb->local_nls, | 939 | full_path, cifs_sb->local_nls, |
925 | cifs_sb->mnt_cifs_flags & | 940 | cifs_sb->mnt_cifs_flags & |
926 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 941 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
927 | if (rc) { | 942 | if (rc == -EOPNOTSUPP) { |
943 | kfree(pInfo); | ||
944 | goto mkdir_retry_old; | ||
945 | } else if (rc) { | ||
928 | cFYI(1, ("posix mkdir returned 0x%x", rc)); | 946 | cFYI(1, ("posix mkdir returned 0x%x", rc)); |
929 | d_drop(direntry); | 947 | d_drop(direntry); |
930 | } else { | 948 | } else { |
931 | int obj_type; | 949 | int obj_type; |
932 | if (pInfo->Type == -1) /* no return info - go query */ | 950 | if (pInfo->Type == cpu_to_le32(-1)) { |
951 | /* no return info, go query for it */ | ||
952 | kfree(pInfo); | ||
933 | goto mkdir_get_info; | 953 | goto mkdir_get_info; |
954 | } | ||
934 | /*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need | 955 | /*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need |
935 | to set uid/gid */ | 956 | to set uid/gid */ |
936 | inc_nlink(inode); | 957 | inc_nlink(inode); |
@@ -940,8 +961,10 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) | |||
940 | direntry->d_op = &cifs_dentry_ops; | 961 | direntry->d_op = &cifs_dentry_ops; |
941 | 962 | ||
942 | newinode = new_inode(inode->i_sb); | 963 | newinode = new_inode(inode->i_sb); |
943 | if (newinode == NULL) | 964 | if (newinode == NULL) { |
965 | kfree(pInfo); | ||
944 | goto mkdir_get_info; | 966 | goto mkdir_get_info; |
967 | } | ||
945 | /* Is an i_ino of zero legal? */ | 968 | /* Is an i_ino of zero legal? */ |
946 | /* Are there sanity checks we can use to ensure that | 969 | /* Are there sanity checks we can use to ensure that |
947 | the server is really filling in that field? */ | 970 | the server is really filling in that field? */ |
@@ -972,7 +995,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) | |||
972 | kfree(pInfo); | 995 | kfree(pInfo); |
973 | goto mkdir_out; | 996 | goto mkdir_out; |
974 | } | 997 | } |
975 | 998 | mkdir_retry_old: | |
976 | /* BB add setting the equivalent of mode via CreateX w/ACLs */ | 999 | /* BB add setting the equivalent of mode via CreateX w/ACLs */ |
977 | rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls, | 1000 | rc = CIFSSMBMkDir(xid, pTcon, full_path, cifs_sb->local_nls, |
978 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | 1001 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); |
@@ -1377,8 +1400,17 @@ static int cifs_vmtruncate(struct inode *inode, loff_t offset) | |||
1377 | } | 1400 | } |
1378 | i_size_write(inode, offset); | 1401 | i_size_write(inode, offset); |
1379 | spin_unlock(&inode->i_lock); | 1402 | spin_unlock(&inode->i_lock); |
1403 | /* | ||
1404 | * unmap_mapping_range is called twice, first simply for efficiency | ||
1405 | * so that truncate_inode_pages does fewer single-page unmaps. However | ||
1406 | * after this first call, and before truncate_inode_pages finishes, | ||
1407 | * it is possible for private pages to be COWed, which remain after | ||
1408 | * truncate_inode_pages finishes, hence the second unmap_mapping_range | ||
1409 | * call must be made for correctness. | ||
1410 | */ | ||
1380 | unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); | 1411 | unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); |
1381 | truncate_inode_pages(mapping, offset); | 1412 | truncate_inode_pages(mapping, offset); |
1413 | unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1); | ||
1382 | goto out_truncate; | 1414 | goto out_truncate; |
1383 | 1415 | ||
1384 | do_expand: | 1416 | do_expand: |
@@ -1469,7 +1501,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
1469 | atomic_dec(&open_file->wrtPending); | 1501 | atomic_dec(&open_file->wrtPending); |
1470 | cFYI(1, ("SetFSize for attrs rc = %d", rc)); | 1502 | cFYI(1, ("SetFSize for attrs rc = %d", rc)); |
1471 | if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { | 1503 | if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) { |
1472 | int bytes_written; | 1504 | unsigned int bytes_written; |
1473 | rc = CIFSSMBWrite(xid, pTcon, | 1505 | rc = CIFSSMBWrite(xid, pTcon, |
1474 | nfid, 0, attrs->ia_size, | 1506 | nfid, 0, attrs->ia_size, |
1475 | &bytes_written, NULL, NULL, | 1507 | &bytes_written, NULL, NULL, |
@@ -1502,7 +1534,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
1502 | cifs_sb->mnt_cifs_flags & | 1534 | cifs_sb->mnt_cifs_flags & |
1503 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 1535 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
1504 | if (rc == 0) { | 1536 | if (rc == 0) { |
1505 | int bytes_written; | 1537 | unsigned int bytes_written; |
1506 | rc = CIFSSMBWrite(xid, pTcon, | 1538 | rc = CIFSSMBWrite(xid, pTcon, |
1507 | netfid, 0, | 1539 | netfid, 0, |
1508 | attrs->ia_size, | 1540 | attrs->ia_size, |
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 6a85ef7b8797..11f265726db7 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
@@ -237,7 +237,7 @@ cifs_readlink(struct dentry *direntry, char __user *pBuffer, int buflen) | |||
237 | char *tmp_path = NULL; | 237 | char *tmp_path = NULL; |
238 | char *tmpbuffer; | 238 | char *tmpbuffer; |
239 | unsigned char *referrals = NULL; | 239 | unsigned char *referrals = NULL; |
240 | int num_referrals = 0; | 240 | unsigned int num_referrals = 0; |
241 | int len; | 241 | int len; |
242 | __u16 fid; | 242 | __u16 fid; |
243 | 243 | ||
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 0bcec0844bee..51ec681fe74a 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c | |||
@@ -169,7 +169,6 @@ cifs_buf_get(void) | |||
169 | void | 169 | void |
170 | cifs_buf_release(void *buf_to_free) | 170 | cifs_buf_release(void *buf_to_free) |
171 | { | 171 | { |
172 | |||
173 | if (buf_to_free == NULL) { | 172 | if (buf_to_free == NULL) { |
174 | /* cFYI(1, ("Null buffer passed to cifs_buf_release"));*/ | 173 | /* cFYI(1, ("Null buffer passed to cifs_buf_release"));*/ |
175 | return; | 174 | return; |
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index 2bfed3f45d0f..f06359cb22ee 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c | |||
@@ -114,10 +114,16 @@ static const struct smb_to_posix_error mapping_table_ERRSRV[] = { | |||
114 | {ERRusempx, -EIO}, | 114 | {ERRusempx, -EIO}, |
115 | {ERRusestd, -EIO}, | 115 | {ERRusestd, -EIO}, |
116 | {ERR_NOTIFY_ENUM_DIR, -ENOBUFS}, | 116 | {ERR_NOTIFY_ENUM_DIR, -ENOBUFS}, |
117 | {ERRaccountexpired, -EACCES}, | 117 | {ERRnoSuchUser, -EACCES}, |
118 | /* {ERRaccountexpired, -EACCES}, | ||
118 | {ERRbadclient, -EACCES}, | 119 | {ERRbadclient, -EACCES}, |
119 | {ERRbadLogonTime, -EACCES}, | 120 | {ERRbadLogonTime, -EACCES}, |
120 | {ERRpasswordExpired, -EACCES}, | 121 | {ERRpasswordExpired, -EACCES},*/ |
122 | {ERRaccountexpired, -EKEYEXPIRED}, | ||
123 | {ERRbadclient, -EACCES}, | ||
124 | {ERRbadLogonTime, -EACCES}, | ||
125 | {ERRpasswordExpired, -EKEYEXPIRED}, | ||
126 | |||
121 | {ERRnosupport, -EINVAL}, | 127 | {ERRnosupport, -EINVAL}, |
122 | {0, 0} | 128 | {0, 0} |
123 | }; | 129 | }; |
@@ -270,7 +276,7 @@ static const struct { | |||
270 | from NT_STATUS_NO_SUCH_USER to NT_STATUS_LOGON_FAILURE | 276 | from NT_STATUS_NO_SUCH_USER to NT_STATUS_LOGON_FAILURE |
271 | during the session setup } */ | 277 | during the session setup } */ |
272 | { | 278 | { |
273 | ERRDOS, ERRnoaccess, NT_STATUS_NO_SUCH_USER}, { | 279 | ERRDOS, ERRnoaccess, NT_STATUS_NO_SUCH_USER}, { /* could map to 2238 */ |
274 | ERRHRD, ERRgeneral, NT_STATUS_GROUP_EXISTS}, { | 280 | ERRHRD, ERRgeneral, NT_STATUS_GROUP_EXISTS}, { |
275 | ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_GROUP}, { | 281 | ERRHRD, ERRgeneral, NT_STATUS_NO_SUCH_GROUP}, { |
276 | ERRHRD, ERRgeneral, NT_STATUS_MEMBER_IN_GROUP}, { | 282 | ERRHRD, ERRgeneral, NT_STATUS_MEMBER_IN_GROUP}, { |
@@ -285,10 +291,10 @@ static const struct { | |||
285 | ERRHRD, ERRgeneral, NT_STATUS_PASSWORD_RESTRICTION}, { | 291 | ERRHRD, ERRgeneral, NT_STATUS_PASSWORD_RESTRICTION}, { |
286 | ERRDOS, ERRnoaccess, NT_STATUS_LOGON_FAILURE}, { | 292 | ERRDOS, ERRnoaccess, NT_STATUS_LOGON_FAILURE}, { |
287 | ERRHRD, ERRgeneral, NT_STATUS_ACCOUNT_RESTRICTION}, { | 293 | ERRHRD, ERRgeneral, NT_STATUS_ACCOUNT_RESTRICTION}, { |
288 | ERRSRV, 2241, NT_STATUS_INVALID_LOGON_HOURS}, { | 294 | ERRSRV, ERRbadLogonTime, NT_STATUS_INVALID_LOGON_HOURS}, { |
289 | ERRSRV, 2240, NT_STATUS_INVALID_WORKSTATION}, { | 295 | ERRSRV, ERRbadclient, NT_STATUS_INVALID_WORKSTATION}, { |
290 | ERRSRV, ERRpasswordExpired, NT_STATUS_PASSWORD_EXPIRED}, { | 296 | ERRSRV, ERRpasswordExpired, NT_STATUS_PASSWORD_EXPIRED}, { |
291 | ERRSRV, 2239, NT_STATUS_ACCOUNT_DISABLED}, { | 297 | ERRSRV, ERRaccountexpired, NT_STATUS_ACCOUNT_DISABLED}, { |
292 | ERRHRD, ERRgeneral, NT_STATUS_NONE_MAPPED}, { | 298 | ERRHRD, ERRgeneral, NT_STATUS_NONE_MAPPED}, { |
293 | ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_LUIDS_REQUESTED}, { | 299 | ERRHRD, ERRgeneral, NT_STATUS_TOO_MANY_LUIDS_REQUESTED}, { |
294 | ERRHRD, ERRgeneral, NT_STATUS_LUIDS_EXHAUSTED}, { | 300 | ERRHRD, ERRgeneral, NT_STATUS_LUIDS_EXHAUSTED}, { |
@@ -585,7 +591,7 @@ static const struct { | |||
585 | ERRDOS, ERRnoaccess, NT_STATUS_TRUST_FAILURE}, { | 591 | ERRDOS, ERRnoaccess, NT_STATUS_TRUST_FAILURE}, { |
586 | ERRHRD, ERRgeneral, NT_STATUS_MUTANT_LIMIT_EXCEEDED}, { | 592 | ERRHRD, ERRgeneral, NT_STATUS_MUTANT_LIMIT_EXCEEDED}, { |
587 | ERRDOS, ERRnetlogonNotStarted, NT_STATUS_NETLOGON_NOT_STARTED}, { | 593 | ERRDOS, ERRnetlogonNotStarted, NT_STATUS_NETLOGON_NOT_STARTED}, { |
588 | ERRSRV, 2239, NT_STATUS_ACCOUNT_EXPIRED}, { | 594 | ERRSRV, ERRaccountexpired, NT_STATUS_ACCOUNT_EXPIRED}, { |
589 | ERRHRD, ERRgeneral, NT_STATUS_POSSIBLE_DEADLOCK}, { | 595 | ERRHRD, ERRgeneral, NT_STATUS_POSSIBLE_DEADLOCK}, { |
590 | ERRHRD, ERRgeneral, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT}, { | 596 | ERRHRD, ERRgeneral, NT_STATUS_NETWORK_CREDENTIAL_CONFLICT}, { |
591 | ERRHRD, ERRgeneral, NT_STATUS_REMOTE_SESSION_LIMIT}, { | 597 | ERRHRD, ERRgeneral, NT_STATUS_REMOTE_SESSION_LIMIT}, { |
@@ -754,7 +760,7 @@ ntstatus_to_dos(__u32 ntstatus, __u8 * eclass, __u16 * ecode) | |||
754 | } | 760 | } |
755 | 761 | ||
756 | int | 762 | int |
757 | map_smb_to_linux_error(struct smb_hdr *smb) | 763 | map_smb_to_linux_error(struct smb_hdr *smb, int logErr) |
758 | { | 764 | { |
759 | unsigned int i; | 765 | unsigned int i; |
760 | int rc = -EIO; /* if transport error smb error may not be set */ | 766 | int rc = -EIO; /* if transport error smb error may not be set */ |
@@ -771,7 +777,9 @@ map_smb_to_linux_error(struct smb_hdr *smb) | |||
771 | /* translate the newer STATUS codes to old style SMB errors | 777 | /* translate the newer STATUS codes to old style SMB errors |
772 | * and then to POSIX errors */ | 778 | * and then to POSIX errors */ |
773 | __u32 err = le32_to_cpu(smb->Status.CifsError); | 779 | __u32 err = le32_to_cpu(smb->Status.CifsError); |
774 | if (cifsFYI & CIFS_RC) | 780 | if (logErr && (err != (NT_STATUS_MORE_PROCESSING_REQUIRED))) |
781 | cifs_print_status(err); | ||
782 | else if (cifsFYI & CIFS_RC) | ||
775 | cifs_print_status(err); | 783 | cifs_print_status(err); |
776 | ntstatus_to_dos(err, &smberrclass, &smberrcode); | 784 | ntstatus_to_dos(err, &smberrclass, &smberrcode); |
777 | } else { | 785 | } else { |
@@ -813,7 +821,7 @@ map_smb_to_linux_error(struct smb_hdr *smb) | |||
813 | } | 821 | } |
814 | /* else ERRHRD class errors or junk - return EIO */ | 822 | /* else ERRHRD class errors or junk - return EIO */ |
815 | 823 | ||
816 | cFYI(1, (" !!Mapping smb error code %d to POSIX err %d !!", | 824 | cFYI(1, ("Mapping smb error code %d to POSIX err %d", |
817 | smberrcode, rc)); | 825 | smberrcode, rc)); |
818 | 826 | ||
819 | /* generic corrective action e.g. reconnect SMB session on | 827 | /* generic corrective action e.g. reconnect SMB session on |
@@ -899,8 +907,11 @@ struct timespec cnvrtDosUnixTm(__u16 date, __u16 time) | |||
899 | cERROR(1, ("illegal hours %d", st->Hours)); | 907 | cERROR(1, ("illegal hours %d", st->Hours)); |
900 | days = sd->Day; | 908 | days = sd->Day; |
901 | month = sd->Month; | 909 | month = sd->Month; |
902 | if ((days > 31) || (month > 12)) | 910 | if ((days > 31) || (month > 12)) { |
903 | cERROR(1, ("illegal date, month %d day: %d", month, days)); | 911 | cERROR(1, ("illegal date, month %d day: %d", month, days)); |
912 | if (month > 12) | ||
913 | month = 12; | ||
914 | } | ||
904 | month -= 1; | 915 | month -= 1; |
905 | days += total_days_of_prev_months[month]; | 916 | days += total_days_of_prev_months[month]; |
906 | days += 3652; /* account for difference in days between 1980 and 1970 */ | 917 | days += 3652; /* account for difference in days between 1980 and 1970 */ |
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 916df9431336..3746580e9701 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -121,7 +121,7 @@ static void AdjustForTZ(struct cifsTconInfo *tcon, struct inode *inode) | |||
121 | 121 | ||
122 | 122 | ||
123 | static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, | 123 | static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, |
124 | char *buf, int *pobject_type, int isNewInode) | 124 | char *buf, unsigned int *pobject_type, int isNewInode) |
125 | { | 125 | { |
126 | loff_t local_size; | 126 | loff_t local_size; |
127 | struct timespec local_mtime; | 127 | struct timespec local_mtime; |
@@ -294,7 +294,7 @@ static void fill_in_inode(struct inode *tmp_inode, int new_buf_type, | |||
294 | } | 294 | } |
295 | 295 | ||
296 | static void unix_fill_in_inode(struct inode *tmp_inode, | 296 | static void unix_fill_in_inode(struct inode *tmp_inode, |
297 | FILE_UNIX_INFO *pfindData, int *pobject_type, int isNewInode) | 297 | FILE_UNIX_INFO *pfindData, unsigned int *pobject_type, int isNewInode) |
298 | { | 298 | { |
299 | loff_t local_size; | 299 | loff_t local_size; |
300 | struct timespec local_mtime; | 300 | struct timespec local_mtime; |
@@ -826,7 +826,7 @@ static int cifs_filldir(char *pfindEntry, struct file *file, | |||
826 | int rc = 0; | 826 | int rc = 0; |
827 | struct qstr qstring; | 827 | struct qstr qstring; |
828 | struct cifsFileInfo *pCifsF; | 828 | struct cifsFileInfo *pCifsF; |
829 | unsigned obj_type; | 829 | unsigned int obj_type; |
830 | ino_t inum; | 830 | ino_t inum; |
831 | struct cifs_sb_info *cifs_sb; | 831 | struct cifs_sb_info *cifs_sb; |
832 | struct inode *tmp_inode; | 832 | struct inode *tmp_inode; |
@@ -1067,7 +1067,7 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) | |||
1067 | for (i = 0; (i < num_to_fill) && (rc == 0); i++) { | 1067 | for (i = 0; (i < num_to_fill) && (rc == 0); i++) { |
1068 | if (current_entry == NULL) { | 1068 | if (current_entry == NULL) { |
1069 | /* evaluate whether this case is an error */ | 1069 | /* evaluate whether this case is an error */ |
1070 | cERROR(1,("past end of SMB num to fill %d i %d", | 1070 | cERROR(1, ("past SMB end, num to fill %d i %d", |
1071 | num_to_fill, i)); | 1071 | num_to_fill, i)); |
1072 | break; | 1072 | break; |
1073 | } | 1073 | } |
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index 892be9b4d1f3..899dc6078d9a 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c | |||
@@ -67,14 +67,59 @@ static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB) | |||
67 | pSMB->req.hdr.Flags2 |= SMBFLG2_DFS; | 67 | pSMB->req.hdr.Flags2 |= SMBFLG2_DFS; |
68 | capabilities |= CAP_DFS; | 68 | capabilities |= CAP_DFS; |
69 | } | 69 | } |
70 | if (ses->capabilities & CAP_UNIX) { | 70 | if (ses->capabilities & CAP_UNIX) |
71 | capabilities |= CAP_UNIX; | 71 | capabilities |= CAP_UNIX; |
72 | } | ||
73 | 72 | ||
74 | /* BB check whether to init vcnum BB */ | 73 | /* BB check whether to init vcnum BB */ |
75 | return capabilities; | 74 | return capabilities; |
76 | } | 75 | } |
77 | 76 | ||
77 | static void | ||
78 | unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp) | ||
79 | { | ||
80 | char *bcc_ptr = *pbcc_area; | ||
81 | int bytes_ret = 0; | ||
82 | |||
83 | /* Copy OS version */ | ||
84 | bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32, | ||
85 | nls_cp); | ||
86 | bcc_ptr += 2 * bytes_ret; | ||
87 | bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release, | ||
88 | 32, nls_cp); | ||
89 | bcc_ptr += 2 * bytes_ret; | ||
90 | bcc_ptr += 2; /* trailing null */ | ||
91 | |||
92 | bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS, | ||
93 | 32, nls_cp); | ||
94 | bcc_ptr += 2 * bytes_ret; | ||
95 | bcc_ptr += 2; /* trailing null */ | ||
96 | |||
97 | *pbcc_area = bcc_ptr; | ||
98 | } | ||
99 | |||
100 | static void unicode_domain_string(char **pbcc_area, struct cifsSesInfo *ses, | ||
101 | const struct nls_table *nls_cp) | ||
102 | { | ||
103 | char *bcc_ptr = *pbcc_area; | ||
104 | int bytes_ret = 0; | ||
105 | |||
106 | /* copy domain */ | ||
107 | if (ses->domainName == NULL) { | ||
108 | /* Sending null domain better than using a bogus domain name (as | ||
109 | we did briefly in 2.6.18) since server will use its default */ | ||
110 | *bcc_ptr = 0; | ||
111 | *(bcc_ptr+1) = 0; | ||
112 | bytes_ret = 0; | ||
113 | } else | ||
114 | bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName, | ||
115 | 256, nls_cp); | ||
116 | bcc_ptr += 2 * bytes_ret; | ||
117 | bcc_ptr += 2; /* account for null terminator */ | ||
118 | |||
119 | *pbcc_area = bcc_ptr; | ||
120 | } | ||
121 | |||
122 | |||
78 | static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses, | 123 | static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses, |
79 | const struct nls_table *nls_cp) | 124 | const struct nls_table *nls_cp) |
80 | { | 125 | { |
@@ -100,32 +145,9 @@ static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses, | |||
100 | } | 145 | } |
101 | bcc_ptr += 2 * bytes_ret; | 146 | bcc_ptr += 2 * bytes_ret; |
102 | bcc_ptr += 2; /* account for null termination */ | 147 | bcc_ptr += 2; /* account for null termination */ |
103 | /* copy domain */ | ||
104 | if (ses->domainName == NULL) { | ||
105 | /* Sending null domain better than using a bogus domain name (as | ||
106 | we did briefly in 2.6.18) since server will use its default */ | ||
107 | *bcc_ptr = 0; | ||
108 | *(bcc_ptr+1) = 0; | ||
109 | bytes_ret = 0; | ||
110 | } else | ||
111 | bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName, | ||
112 | 256, nls_cp); | ||
113 | bcc_ptr += 2 * bytes_ret; | ||
114 | bcc_ptr += 2; /* account for null terminator */ | ||
115 | |||
116 | /* Copy OS version */ | ||
117 | bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32, | ||
118 | nls_cp); | ||
119 | bcc_ptr += 2 * bytes_ret; | ||
120 | bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release, | ||
121 | 32, nls_cp); | ||
122 | bcc_ptr += 2 * bytes_ret; | ||
123 | bcc_ptr += 2; /* trailing null */ | ||
124 | 148 | ||
125 | bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS, | 149 | unicode_domain_string(&bcc_ptr, ses, nls_cp); |
126 | 32, nls_cp); | 150 | unicode_oslm_strings(&bcc_ptr, nls_cp); |
127 | bcc_ptr += 2 * bytes_ret; | ||
128 | bcc_ptr += 2; /* trailing null */ | ||
129 | 151 | ||
130 | *pbcc_area = bcc_ptr; | 152 | *pbcc_area = bcc_ptr; |
131 | } | 153 | } |
@@ -203,14 +225,11 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft, | |||
203 | if (len >= words_left) | 225 | if (len >= words_left) |
204 | return rc; | 226 | return rc; |
205 | 227 | ||
206 | if (ses->serverOS) | 228 | kfree(ses->serverOS); |
207 | kfree(ses->serverOS); | ||
208 | /* UTF-8 string will not grow more than four times as big as UCS-16 */ | 229 | /* UTF-8 string will not grow more than four times as big as UCS-16 */ |
209 | ses->serverOS = kzalloc(4 * len, GFP_KERNEL); | 230 | ses->serverOS = kzalloc(4 * len, GFP_KERNEL); |
210 | if (ses->serverOS != NULL) { | 231 | if (ses->serverOS != NULL) |
211 | cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, | 232 | cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, nls_cp); |
212 | nls_cp); | ||
213 | } | ||
214 | data += 2 * (len + 1); | 233 | data += 2 * (len + 1); |
215 | words_left -= len + 1; | 234 | words_left -= len + 1; |
216 | 235 | ||
@@ -220,8 +239,7 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft, | |||
220 | if (len >= words_left) | 239 | if (len >= words_left) |
221 | return rc; | 240 | return rc; |
222 | 241 | ||
223 | if (ses->serverNOS) | 242 | kfree(ses->serverNOS); |
224 | kfree(ses->serverNOS); | ||
225 | ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */ | 243 | ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */ |
226 | if (ses->serverNOS != NULL) { | 244 | if (ses->serverNOS != NULL) { |
227 | cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len, | 245 | cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len, |
@@ -240,8 +258,7 @@ static int decode_unicode_ssetup(char **pbcc_area, int bleft, | |||
240 | if (len > words_left) | 258 | if (len > words_left) |
241 | return rc; | 259 | return rc; |
242 | 260 | ||
243 | if (ses->serverDomain) | 261 | kfree(ses->serverDomain); |
244 | kfree(ses->serverDomain); | ||
245 | ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */ | 262 | ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */ |
246 | if (ses->serverDomain != NULL) { | 263 | if (ses->serverDomain != NULL) { |
247 | cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len, | 264 | cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len, |
@@ -271,8 +288,7 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft, | |||
271 | if (len >= bleft) | 288 | if (len >= bleft) |
272 | return rc; | 289 | return rc; |
273 | 290 | ||
274 | if (ses->serverOS) | 291 | kfree(ses->serverOS); |
275 | kfree(ses->serverOS); | ||
276 | 292 | ||
277 | ses->serverOS = kzalloc(len + 1, GFP_KERNEL); | 293 | ses->serverOS = kzalloc(len + 1, GFP_KERNEL); |
278 | if (ses->serverOS) | 294 | if (ses->serverOS) |
@@ -289,8 +305,7 @@ static int decode_ascii_ssetup(char **pbcc_area, int bleft, | |||
289 | if (len >= bleft) | 305 | if (len >= bleft) |
290 | return rc; | 306 | return rc; |
291 | 307 | ||
292 | if (ses->serverNOS) | 308 | kfree(ses->serverNOS); |
293 | kfree(ses->serverNOS); | ||
294 | 309 | ||
295 | ses->serverNOS = kzalloc(len + 1, GFP_KERNEL); | 310 | ses->serverNOS = kzalloc(len + 1, GFP_KERNEL); |
296 | if (ses->serverNOS) | 311 | if (ses->serverNOS) |
@@ -479,7 +494,8 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, | |||
479 | if (ses->capabilities & CAP_UNICODE) { | 494 | if (ses->capabilities & CAP_UNICODE) { |
480 | if (iov[0].iov_len % 2) { | 495 | if (iov[0].iov_len % 2) { |
481 | *bcc_ptr = 0; | 496 | *bcc_ptr = 0; |
482 | } bcc_ptr++; | 497 | bcc_ptr++; |
498 | } | ||
483 | unicode_ssetup_strings(&bcc_ptr, ses, nls_cp); | 499 | unicode_ssetup_strings(&bcc_ptr, ses, nls_cp); |
484 | } else | 500 | } else |
485 | ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); | 501 | ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); |
@@ -497,7 +513,8 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, | |||
497 | 513 | ||
498 | iov[1].iov_base = str_area; | 514 | iov[1].iov_base = str_area; |
499 | iov[1].iov_len = count; | 515 | iov[1].iov_len = count; |
500 | rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, 0); | 516 | rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, |
517 | 0 /* not long op */, 1 /* log NT STATUS if any */ ); | ||
501 | /* SMB request buf freed in SendReceive2 */ | 518 | /* SMB request buf freed in SendReceive2 */ |
502 | 519 | ||
503 | cFYI(1, ("ssetup rc from sendrecv2 is %d", rc)); | 520 | cFYI(1, ("ssetup rc from sendrecv2 is %d", rc)); |
diff --git a/fs/cifs/smberr.h b/fs/cifs/smberr.h index 2ef0be288820..7f50e8577c1c 100644 --- a/fs/cifs/smberr.h +++ b/fs/cifs/smberr.h | |||
@@ -173,9 +173,10 @@ | |||
173 | #define ERRusestd 251 /* temporarily unable to use either raw | 173 | #define ERRusestd 251 /* temporarily unable to use either raw |
174 | or mpx */ | 174 | or mpx */ |
175 | #define ERR_NOTIFY_ENUM_DIR 1024 | 175 | #define ERR_NOTIFY_ENUM_DIR 1024 |
176 | #define ERRnoSuchUser 2238 /* user account does not exist */ | ||
176 | #define ERRaccountexpired 2239 | 177 | #define ERRaccountexpired 2239 |
177 | #define ERRbadclient 2240 | 178 | #define ERRbadclient 2240 /* can not logon from this client */ |
178 | #define ERRbadLogonTime 2241 | 179 | #define ERRbadLogonTime 2241 /* logon hours do not allow this */ |
179 | #define ERRpasswordExpired 2242 | 180 | #define ERRpasswordExpired 2242 |
180 | #define ERRnetlogonNotStarted 2455 | 181 | #define ERRnetlogonNotStarted 2455 |
181 | #define ERRnosupport 0xFFFF | 182 | #define ERRnosupport 0xFFFF |
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 746bc9405db1..7ed32b3cb781 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c | |||
@@ -55,7 +55,7 @@ AllocMidQEntry(const struct smb_hdr *smb_buffer, struct cifsSesInfo *ses) | |||
55 | if (temp == NULL) | 55 | if (temp == NULL) |
56 | return temp; | 56 | return temp; |
57 | else { | 57 | else { |
58 | memset(temp, 0, sizeof (struct mid_q_entry)); | 58 | memset(temp, 0, sizeof(struct mid_q_entry)); |
59 | temp->mid = smb_buffer->Mid; /* always LE */ | 59 | temp->mid = smb_buffer->Mid; /* always LE */ |
60 | temp->pid = current->pid; | 60 | temp->pid = current->pid; |
61 | temp->command = smb_buffer->Command; | 61 | temp->command = smb_buffer->Command; |
@@ -158,7 +158,7 @@ smb_send(struct socket *ssocket, struct smb_hdr *smb_buffer, | |||
158 | iov.iov_len = len; | 158 | iov.iov_len = len; |
159 | 159 | ||
160 | smb_msg.msg_name = sin; | 160 | smb_msg.msg_name = sin; |
161 | smb_msg.msg_namelen = sizeof (struct sockaddr); | 161 | smb_msg.msg_namelen = sizeof(struct sockaddr); |
162 | smb_msg.msg_control = NULL; | 162 | smb_msg.msg_control = NULL; |
163 | smb_msg.msg_controllen = 0; | 163 | smb_msg.msg_controllen = 0; |
164 | smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/ | 164 | smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/ |
@@ -228,7 +228,7 @@ smb_send2(struct socket *ssocket, struct kvec *iov, int n_vec, | |||
228 | return -ENOTSOCK; /* BB eventually add reconnect code here */ | 228 | return -ENOTSOCK; /* BB eventually add reconnect code here */ |
229 | 229 | ||
230 | smb_msg.msg_name = sin; | 230 | smb_msg.msg_name = sin; |
231 | smb_msg.msg_namelen = sizeof (struct sockaddr); | 231 | smb_msg.msg_namelen = sizeof(struct sockaddr); |
232 | smb_msg.msg_control = NULL; | 232 | smb_msg.msg_control = NULL; |
233 | smb_msg.msg_controllen = 0; | 233 | smb_msg.msg_controllen = 0; |
234 | smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/ | 234 | smb_msg.msg_flags = MSG_DONTWAIT + MSG_NOSIGNAL; /* BB add more flags?*/ |
@@ -363,9 +363,8 @@ static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf, | |||
363 | } /* else ok - we are setting up session */ | 363 | } /* else ok - we are setting up session */ |
364 | } | 364 | } |
365 | *ppmidQ = AllocMidQEntry(in_buf, ses); | 365 | *ppmidQ = AllocMidQEntry(in_buf, ses); |
366 | if (*ppmidQ == NULL) { | 366 | if (*ppmidQ == NULL) |
367 | return -ENOMEM; | 367 | return -ENOMEM; |
368 | } | ||
369 | return 0; | 368 | return 0; |
370 | } | 369 | } |
371 | 370 | ||
@@ -419,7 +418,7 @@ static int wait_for_response(struct cifsSesInfo *ses, | |||
419 | int | 418 | int |
420 | SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, | 419 | SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, |
421 | struct kvec *iov, int n_vec, int *pRespBufType /* ret */, | 420 | struct kvec *iov, int n_vec, int *pRespBufType /* ret */, |
422 | const int long_op) | 421 | const int long_op, const int logError) |
423 | { | 422 | { |
424 | int rc = 0; | 423 | int rc = 0; |
425 | unsigned int receive_len; | 424 | unsigned int receive_len; |
@@ -465,7 +464,6 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, | |||
465 | wake_up(&ses->server->request_q); | 464 | wake_up(&ses->server->request_q); |
466 | return rc; | 465 | return rc; |
467 | } | 466 | } |
468 | |||
469 | rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number); | 467 | rc = cifs_sign_smb2(iov, n_vec, ses->server, &midQ->sequence_number); |
470 | 468 | ||
471 | midQ->midState = MID_REQUEST_SUBMITTED; | 469 | midQ->midState = MID_REQUEST_SUBMITTED; |
@@ -568,13 +566,11 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, | |||
568 | } | 566 | } |
569 | 567 | ||
570 | /* BB special case reconnect tid and uid here? */ | 568 | /* BB special case reconnect tid and uid here? */ |
571 | /* BB special case Errbadpassword and pwdexpired here */ | 569 | rc = map_smb_to_linux_error(midQ->resp_buf, logError); |
572 | rc = map_smb_to_linux_error(midQ->resp_buf); | ||
573 | 570 | ||
574 | /* convert ByteCount if necessary */ | 571 | /* convert ByteCount if necessary */ |
575 | if (receive_len >= | 572 | if (receive_len >= sizeof(struct smb_hdr) - 4 |
576 | sizeof (struct smb_hdr) - | 573 | /* do not count RFC1001 header */ + |
577 | 4 /* do not count RFC1001 header */ + | ||
578 | (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ ) | 574 | (2 * midQ->resp_buf->WordCount) + 2 /* bcc */ ) |
579 | BCC(midQ->resp_buf) = | 575 | BCC(midQ->resp_buf) = |
580 | le16_to_cpu(BCC_LE(midQ->resp_buf)); | 576 | le16_to_cpu(BCC_LE(midQ->resp_buf)); |
@@ -749,12 +745,11 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, | |||
749 | *pbytes_returned = out_buf->smb_buf_length; | 745 | *pbytes_returned = out_buf->smb_buf_length; |
750 | 746 | ||
751 | /* BB special case reconnect tid and uid here? */ | 747 | /* BB special case reconnect tid and uid here? */ |
752 | rc = map_smb_to_linux_error(out_buf); | 748 | rc = map_smb_to_linux_error(out_buf, 0 /* no log */ ); |
753 | 749 | ||
754 | /* convert ByteCount if necessary */ | 750 | /* convert ByteCount if necessary */ |
755 | if (receive_len >= | 751 | if (receive_len >= sizeof(struct smb_hdr) - 4 |
756 | sizeof (struct smb_hdr) - | 752 | /* do not count RFC1001 header */ + |
757 | 4 /* do not count RFC1001 header */ + | ||
758 | (2 * out_buf->WordCount) + 2 /* bcc */ ) | 753 | (2 * out_buf->WordCount) + 2 /* bcc */ ) |
759 | BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf)); | 754 | BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf)); |
760 | } else { | 755 | } else { |
@@ -993,12 +988,11 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, | |||
993 | *pbytes_returned = out_buf->smb_buf_length; | 988 | *pbytes_returned = out_buf->smb_buf_length; |
994 | 989 | ||
995 | /* BB special case reconnect tid and uid here? */ | 990 | /* BB special case reconnect tid and uid here? */ |
996 | rc = map_smb_to_linux_error(out_buf); | 991 | rc = map_smb_to_linux_error(out_buf, 0 /* no log */ ); |
997 | 992 | ||
998 | /* convert ByteCount if necessary */ | 993 | /* convert ByteCount if necessary */ |
999 | if (receive_len >= | 994 | if (receive_len >= sizeof(struct smb_hdr) - 4 |
1000 | sizeof (struct smb_hdr) - | 995 | /* do not count RFC1001 header */ + |
1001 | 4 /* do not count RFC1001 header */ + | ||
1002 | (2 * out_buf->WordCount) + 2 /* bcc */ ) | 996 | (2 * out_buf->WordCount) + 2 /* bcc */ ) |
1003 | BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf)); | 997 | BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf)); |
1004 | } else { | 998 | } else { |
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index f61e433d281c..369e838bebd3 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c | |||
@@ -261,21 +261,26 @@ ssize_t cifs_getxattr(struct dentry *direntry, const char *ea_name, | |||
261 | cifs_sb->local_nls, | 261 | cifs_sb->local_nls, |
262 | cifs_sb->mnt_cifs_flags & | 262 | cifs_sb->mnt_cifs_flags & |
263 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 263 | CIFS_MOUNT_MAP_SPECIAL_CHR); |
264 | /* else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | 264 | #ifdef CONFIG_CIFS_EXPERIMENTAL |
265 | else if(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | ||
265 | __u16 fid; | 266 | __u16 fid; |
266 | int oplock = FALSE; | 267 | int oplock = FALSE; |
267 | rc = CIFSSMBOpen(xid, pTcon, full_path, | 268 | if (experimEnabled) |
268 | FILE_OPEN, GENERIC_READ, 0, &fid, | 269 | rc = CIFSSMBOpen(xid, pTcon, full_path, |
269 | &oplock, NULL, cifs_sb->local_nls, | 270 | FILE_OPEN, GENERIC_READ, 0, &fid, |
270 | cifs_sb->mnt_cifs_flags & | 271 | &oplock, NULL, cifs_sb->local_nls, |
271 | CIFS_MOUNT_MAP_SPECIAL_CHR); | 272 | cifs_sb->mnt_cifs_flags & |
273 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
274 | /* else rc is EOPNOTSUPP from above */ | ||
275 | |||
272 | if(rc == 0) { | 276 | if(rc == 0) { |
273 | rc = CIFSSMBGetCIFSACL(xid, pTcon, fid, | 277 | rc = CIFSSMBGetCIFSACL(xid, pTcon, fid, |
274 | ea_value, buf_size, | 278 | ea_value, buf_size, |
275 | ACL_TYPE_ACCESS); | 279 | ACL_TYPE_ACCESS); |
276 | CIFSSMBClose(xid, pTcon, fid); | 280 | CIFSSMBClose(xid, pTcon, fid); |
277 | } | 281 | } |
278 | } */ /* BB enable after fixing up return data */ | 282 | } |
283 | #endif /* EXPERIMENTAL */ | ||
279 | #else | 284 | #else |
280 | cFYI(1, ("query POSIX ACL not supported yet")); | 285 | cFYI(1, ("query POSIX ACL not supported yet")); |
281 | #endif /* CONFIG_CIFS_POSIX */ | 286 | #endif /* CONFIG_CIFS_POSIX */ |
diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c index cdb4c07a7870..359e531094dd 100644 --- a/fs/coda/upcall.c +++ b/fs/coda/upcall.c | |||
@@ -51,7 +51,7 @@ static void *alloc_upcall(int opcode, int size) | |||
51 | 51 | ||
52 | inp->ih.opcode = opcode; | 52 | inp->ih.opcode = opcode; |
53 | inp->ih.pid = current->pid; | 53 | inp->ih.pid = current->pid; |
54 | inp->ih.pgid = process_group(current); | 54 | inp->ih.pgid = task_pgrp_nr(current); |
55 | #ifdef CONFIG_CODA_FS_OLD_API | 55 | #ifdef CONFIG_CODA_FS_OLD_API |
56 | memset(&inp->ih.cred, 0, sizeof(struct coda_cred)); | 56 | memset(&inp->ih.cred, 0, sizeof(struct coda_cred)); |
57 | inp->ih.cred.cr_fsuid = current->fsuid; | 57 | inp->ih.cred.cr_fsuid = current->fsuid; |
diff --git a/fs/dlm/user.c b/fs/dlm/user.c index 6438941ab1f8..4f741546f4bb 100644 --- a/fs/dlm/user.c +++ b/fs/dlm/user.c | |||
@@ -456,7 +456,7 @@ static int check_version(struct dlm_write_request *req) | |||
456 | printk(KERN_DEBUG "dlm: process %s (%d) version mismatch " | 456 | printk(KERN_DEBUG "dlm: process %s (%d) version mismatch " |
457 | "user (%d.%d.%d) kernel (%d.%d.%d)\n", | 457 | "user (%d.%d.%d) kernel (%d.%d.%d)\n", |
458 | current->comm, | 458 | current->comm, |
459 | current->pid, | 459 | task_pid_nr(current), |
460 | req->version[0], | 460 | req->version[0], |
461 | req->version[1], | 461 | req->version[1], |
462 | req->version[2], | 462 | req->version[2], |
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index de6189291954..34f68f3a069a 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -325,15 +325,14 @@ static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq) | |||
325 | int wake_nests = 0; | 325 | int wake_nests = 0; |
326 | unsigned long flags; | 326 | unsigned long flags; |
327 | struct task_struct *this_task = current; | 327 | struct task_struct *this_task = current; |
328 | struct list_head *lsthead = &psw->wake_task_list, *lnk; | 328 | struct list_head *lsthead = &psw->wake_task_list; |
329 | struct wake_task_node *tncur; | 329 | struct wake_task_node *tncur; |
330 | struct wake_task_node tnode; | 330 | struct wake_task_node tnode; |
331 | 331 | ||
332 | spin_lock_irqsave(&psw->lock, flags); | 332 | spin_lock_irqsave(&psw->lock, flags); |
333 | 333 | ||
334 | /* Try to see if the current task is already inside this wakeup call */ | 334 | /* Try to see if the current task is already inside this wakeup call */ |
335 | list_for_each(lnk, lsthead) { | 335 | list_for_each_entry(tncur, lsthead, llink) { |
336 | tncur = list_entry(lnk, struct wake_task_node, llink); | ||
337 | 336 | ||
338 | if (tncur->wq == wq || | 337 | if (tncur->wq == wq || |
339 | (tncur->task == this_task && ++wake_nests > EP_MAX_POLLWAKE_NESTS)) { | 338 | (tncur->task == this_task && ++wake_nests > EP_MAX_POLLWAKE_NESTS)) { |
@@ -234,7 +234,7 @@ static int __bprm_mm_init(struct linux_binprm *bprm) | |||
234 | vma->vm_start = vma->vm_end - PAGE_SIZE; | 234 | vma->vm_start = vma->vm_end - PAGE_SIZE; |
235 | 235 | ||
236 | vma->vm_flags = VM_STACK_FLAGS; | 236 | vma->vm_flags = VM_STACK_FLAGS; |
237 | vma->vm_page_prot = protection_map[vma->vm_flags & 0x7]; | 237 | vma->vm_page_prot = vm_get_page_prot(vma->vm_flags); |
238 | err = insert_vm_struct(mm, vma); | 238 | err = insert_vm_struct(mm, vma); |
239 | if (err) { | 239 | if (err) { |
240 | up_write(&mm->mmap_sem); | 240 | up_write(&mm->mmap_sem); |
@@ -775,8 +775,8 @@ static int de_thread(struct task_struct *tsk) | |||
775 | * Reparenting needs write_lock on tasklist_lock, | 775 | * Reparenting needs write_lock on tasklist_lock, |
776 | * so it is safe to do it under read_lock. | 776 | * so it is safe to do it under read_lock. |
777 | */ | 777 | */ |
778 | if (unlikely(tsk->group_leader == child_reaper(tsk))) | 778 | if (unlikely(tsk->group_leader == task_child_reaper(tsk))) |
779 | tsk->nsproxy->pid_ns->child_reaper = tsk; | 779 | task_active_pid_ns(tsk)->child_reaper = tsk; |
780 | 780 | ||
781 | zap_other_threads(tsk); | 781 | zap_other_threads(tsk); |
782 | read_unlock(&tasklist_lock); | 782 | read_unlock(&tasklist_lock); |
@@ -841,8 +841,8 @@ static int de_thread(struct task_struct *tsk) | |||
841 | */ | 841 | */ |
842 | tsk->start_time = leader->start_time; | 842 | tsk->start_time = leader->start_time; |
843 | 843 | ||
844 | BUG_ON(leader->tgid != tsk->tgid); | 844 | BUG_ON(!same_thread_group(leader, tsk)); |
845 | BUG_ON(tsk->pid == tsk->tgid); | 845 | BUG_ON(has_group_leader_pid(tsk)); |
846 | /* | 846 | /* |
847 | * An exec() starts a new thread group with the | 847 | * An exec() starts a new thread group with the |
848 | * TGID of the previous thread group. Rehash the | 848 | * TGID of the previous thread group. Rehash the |
@@ -857,7 +857,7 @@ static int de_thread(struct task_struct *tsk) | |||
857 | */ | 857 | */ |
858 | detach_pid(tsk, PIDTYPE_PID); | 858 | detach_pid(tsk, PIDTYPE_PID); |
859 | tsk->pid = leader->pid; | 859 | tsk->pid = leader->pid; |
860 | attach_pid(tsk, PIDTYPE_PID, find_pid(tsk->pid)); | 860 | attach_pid(tsk, PIDTYPE_PID, task_pid(leader)); |
861 | transfer_pid(leader, tsk, PIDTYPE_PGID); | 861 | transfer_pid(leader, tsk, PIDTYPE_PGID); |
862 | transfer_pid(leader, tsk, PIDTYPE_SID); | 862 | transfer_pid(leader, tsk, PIDTYPE_SID); |
863 | list_replace_rcu(&leader->tasks, &tsk->tasks); | 863 | list_replace_rcu(&leader->tasks, &tsk->tasks); |
@@ -1433,7 +1433,7 @@ static int format_corename(char *corename, const char *pattern, long signr) | |||
1433 | case 'p': | 1433 | case 'p': |
1434 | pid_in_pattern = 1; | 1434 | pid_in_pattern = 1; |
1435 | rc = snprintf(out_ptr, out_end - out_ptr, | 1435 | rc = snprintf(out_ptr, out_end - out_ptr, |
1436 | "%d", current->tgid); | 1436 | "%d", task_tgid_vnr(current)); |
1437 | if (rc > out_end - out_ptr) | 1437 | if (rc > out_end - out_ptr) |
1438 | goto out; | 1438 | goto out; |
1439 | out_ptr += rc; | 1439 | out_ptr += rc; |
@@ -1513,7 +1513,7 @@ static int format_corename(char *corename, const char *pattern, long signr) | |||
1513 | if (!ispipe && !pid_in_pattern | 1513 | if (!ispipe && !pid_in_pattern |
1514 | && (core_uses_pid || atomic_read(¤t->mm->mm_users) != 1)) { | 1514 | && (core_uses_pid || atomic_read(¤t->mm->mm_users) != 1)) { |
1515 | rc = snprintf(out_ptr, out_end - out_ptr, | 1515 | rc = snprintf(out_ptr, out_end - out_ptr, |
1516 | ".%d", current->tgid); | 1516 | ".%d", task_tgid_vnr(current)); |
1517 | if (rc > out_end - out_ptr) | 1517 | if (rc > out_end - out_ptr) |
1518 | goto out; | 1518 | goto out; |
1519 | out_ptr += rc; | 1519 | out_ptr += rc; |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 3dec003b773e..9b162cd6c16c 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -2954,7 +2954,7 @@ int ext3_write_inode(struct inode *inode, int wait) | |||
2954 | return 0; | 2954 | return 0; |
2955 | 2955 | ||
2956 | if (ext3_journal_current_handle()) { | 2956 | if (ext3_journal_current_handle()) { |
2957 | jbd_debug(0, "called recursively, non-PF_MEMALLOC!\n"); | 2957 | jbd_debug(1, "called recursively, non-PF_MEMALLOC!\n"); |
2958 | dump_stack(); | 2958 | dump_stack(); |
2959 | return -EIO; | 2959 | return -EIO; |
2960 | } | 2960 | } |
diff --git a/fs/ext3/xattr.c b/fs/ext3/xattr.c index f58cbb26323e..408373819e34 100644 --- a/fs/ext3/xattr.c +++ b/fs/ext3/xattr.c | |||
@@ -741,12 +741,11 @@ ext3_xattr_block_set(handle_t *handle, struct inode *inode, | |||
741 | } | 741 | } |
742 | } else { | 742 | } else { |
743 | /* Allocate a buffer where we construct the new block. */ | 743 | /* Allocate a buffer where we construct the new block. */ |
744 | s->base = kmalloc(sb->s_blocksize, GFP_KERNEL); | 744 | s->base = kzalloc(sb->s_blocksize, GFP_KERNEL); |
745 | /* assert(header == s->base) */ | 745 | /* assert(header == s->base) */ |
746 | error = -ENOMEM; | 746 | error = -ENOMEM; |
747 | if (s->base == NULL) | 747 | if (s->base == NULL) |
748 | goto cleanup; | 748 | goto cleanup; |
749 | memset(s->base, 0, sb->s_blocksize); | ||
750 | header(s->base)->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC); | 749 | header(s->base)->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC); |
751 | header(s->base)->h_blocks = cpu_to_le32(1); | 750 | header(s->base)->h_blocks = cpu_to_le32(1); |
752 | header(s->base)->h_refcount = cpu_to_le32(1); | 751 | header(s->base)->h_refcount = cpu_to_le32(1); |
diff --git a/fs/fcntl.c b/fs/fcntl.c index c9db73fc5e3d..8685263ccc4a 100644 --- a/fs/fcntl.c +++ b/fs/fcntl.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/ptrace.h> | 18 | #include <linux/ptrace.h> |
19 | #include <linux/signal.h> | 19 | #include <linux/signal.h> |
20 | #include <linux/rcupdate.h> | 20 | #include <linux/rcupdate.h> |
21 | #include <linux/pid_namespace.h> | ||
21 | 22 | ||
22 | #include <asm/poll.h> | 23 | #include <asm/poll.h> |
23 | #include <asm/siginfo.h> | 24 | #include <asm/siginfo.h> |
@@ -292,7 +293,7 @@ int f_setown(struct file *filp, unsigned long arg, int force) | |||
292 | who = -who; | 293 | who = -who; |
293 | } | 294 | } |
294 | rcu_read_lock(); | 295 | rcu_read_lock(); |
295 | pid = find_pid(who); | 296 | pid = find_vpid(who); |
296 | result = __f_setown(filp, pid, type, force); | 297 | result = __f_setown(filp, pid, type, force); |
297 | rcu_read_unlock(); | 298 | rcu_read_unlock(); |
298 | return result; | 299 | return result; |
@@ -308,7 +309,7 @@ pid_t f_getown(struct file *filp) | |||
308 | { | 309 | { |
309 | pid_t pid; | 310 | pid_t pid; |
310 | read_lock(&filp->f_owner.lock); | 311 | read_lock(&filp->f_owner.lock); |
311 | pid = pid_nr(filp->f_owner.pid); | 312 | pid = pid_nr_ns(filp->f_owner.pid, current->nsproxy->pid_ns); |
312 | if (filp->f_owner.pid_type == PIDTYPE_PGID) | 313 | if (filp->f_owner.pid_type == PIDTYPE_PGID) |
313 | pid = -pid; | 314 | pid = -pid; |
314 | read_unlock(&filp->f_owner.lock); | 315 | read_unlock(&filp->f_owner.lock); |
diff --git a/fs/file_table.c b/fs/file_table.c index 3176fefc92e1..664e3f2309b8 100644 --- a/fs/file_table.c +++ b/fs/file_table.c | |||
@@ -323,12 +323,11 @@ void file_kill(struct file *file) | |||
323 | 323 | ||
324 | int fs_may_remount_ro(struct super_block *sb) | 324 | int fs_may_remount_ro(struct super_block *sb) |
325 | { | 325 | { |
326 | struct list_head *p; | 326 | struct file *file; |
327 | 327 | ||
328 | /* Check that no files are currently opened for writing. */ | 328 | /* Check that no files are currently opened for writing. */ |
329 | file_list_lock(); | 329 | file_list_lock(); |
330 | list_for_each(p, &sb->s_files) { | 330 | list_for_each_entry(file, &sb->s_files, f_u.fu_list) { |
331 | struct file *file = list_entry(p, struct file, f_u.fu_list); | ||
332 | struct inode *inode = file->f_path.dentry->d_inode; | 331 | struct inode *inode = file->f_path.dentry->d_inode; |
333 | 332 | ||
334 | /* File with pending delete? */ | 333 | /* File with pending delete? */ |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 686734ff973d..0fca82021d76 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -89,7 +89,7 @@ void __mark_inode_dirty(struct inode *inode, int flags) | |||
89 | if (inode->i_ino || strcmp(inode->i_sb->s_id, "bdev")) | 89 | if (inode->i_ino || strcmp(inode->i_sb->s_id, "bdev")) |
90 | printk(KERN_DEBUG | 90 | printk(KERN_DEBUG |
91 | "%s(%d): dirtied inode %lu (%s) on %s\n", | 91 | "%s(%d): dirtied inode %lu (%s) on %s\n", |
92 | current->comm, current->pid, inode->i_ino, | 92 | current->comm, task_pid_nr(current), inode->i_ino, |
93 | name, inode->i_sb->s_id); | 93 | name, inode->i_sb->s_id); |
94 | } | 94 | } |
95 | 95 | ||
diff --git a/fs/ioprio.c b/fs/ioprio.c index 10d2c211d18b..d6ff77e8e7ec 100644 --- a/fs/ioprio.c +++ b/fs/ioprio.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/capability.h> | 25 | #include <linux/capability.h> |
26 | #include <linux/syscalls.h> | 26 | #include <linux/syscalls.h> |
27 | #include <linux/security.h> | 27 | #include <linux/security.h> |
28 | #include <linux/pid_namespace.h> | ||
28 | 29 | ||
29 | static int set_task_ioprio(struct task_struct *task, int ioprio) | 30 | static int set_task_ioprio(struct task_struct *task, int ioprio) |
30 | { | 31 | { |
@@ -93,7 +94,7 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio) | |||
93 | if (!who) | 94 | if (!who) |
94 | p = current; | 95 | p = current; |
95 | else | 96 | else |
96 | p = find_task_by_pid(who); | 97 | p = find_task_by_vpid(who); |
97 | if (p) | 98 | if (p) |
98 | ret = set_task_ioprio(p, ioprio); | 99 | ret = set_task_ioprio(p, ioprio); |
99 | break; | 100 | break; |
@@ -101,7 +102,7 @@ asmlinkage long sys_ioprio_set(int which, int who, int ioprio) | |||
101 | if (!who) | 102 | if (!who) |
102 | pgrp = task_pgrp(current); | 103 | pgrp = task_pgrp(current); |
103 | else | 104 | else |
104 | pgrp = find_pid(who); | 105 | pgrp = find_vpid(who); |
105 | do_each_pid_task(pgrp, PIDTYPE_PGID, p) { | 106 | do_each_pid_task(pgrp, PIDTYPE_PGID, p) { |
106 | ret = set_task_ioprio(p, ioprio); | 107 | ret = set_task_ioprio(p, ioprio); |
107 | if (ret) | 108 | if (ret) |
@@ -180,7 +181,7 @@ asmlinkage long sys_ioprio_get(int which, int who) | |||
180 | if (!who) | 181 | if (!who) |
181 | p = current; | 182 | p = current; |
182 | else | 183 | else |
183 | p = find_task_by_pid(who); | 184 | p = find_task_by_vpid(who); |
184 | if (p) | 185 | if (p) |
185 | ret = get_task_ioprio(p); | 186 | ret = get_task_ioprio(p); |
186 | break; | 187 | break; |
@@ -188,7 +189,7 @@ asmlinkage long sys_ioprio_get(int which, int who) | |||
188 | if (!who) | 189 | if (!who) |
189 | pgrp = task_pgrp(current); | 190 | pgrp = task_pgrp(current); |
190 | else | 191 | else |
191 | pgrp = find_pid(who); | 192 | pgrp = find_vpid(who); |
192 | do_each_pid_task(pgrp, PIDTYPE_PGID, p) { | 193 | do_each_pid_task(pgrp, PIDTYPE_PGID, p) { |
193 | tmpio = get_task_ioprio(p); | 194 | tmpio = get_task_ioprio(p); |
194 | if (tmpio < 0) | 195 | if (tmpio < 0) |
diff --git a/fs/jbd/commit.c b/fs/jbd/commit.c index a263d82761df..8f1f2aa5fb39 100644 --- a/fs/jbd/commit.c +++ b/fs/jbd/commit.c | |||
@@ -466,7 +466,7 @@ void journal_commit_transaction(journal_t *journal) | |||
466 | spin_unlock(&journal->j_list_lock); | 466 | spin_unlock(&journal->j_list_lock); |
467 | 467 | ||
468 | if (err) | 468 | if (err) |
469 | __journal_abort_hard(journal); | 469 | journal_abort(journal, err); |
470 | 470 | ||
471 | journal_write_revoke_records(journal, commit_transaction); | 471 | journal_write_revoke_records(journal, commit_transaction); |
472 | 472 | ||
@@ -524,7 +524,7 @@ void journal_commit_transaction(journal_t *journal) | |||
524 | 524 | ||
525 | descriptor = journal_get_descriptor_buffer(journal); | 525 | descriptor = journal_get_descriptor_buffer(journal); |
526 | if (!descriptor) { | 526 | if (!descriptor) { |
527 | __journal_abort_hard(journal); | 527 | journal_abort(journal, -EIO); |
528 | continue; | 528 | continue; |
529 | } | 529 | } |
530 | 530 | ||
@@ -557,7 +557,7 @@ void journal_commit_transaction(journal_t *journal) | |||
557 | and repeat this loop: we'll fall into the | 557 | and repeat this loop: we'll fall into the |
558 | refile-on-abort condition above. */ | 558 | refile-on-abort condition above. */ |
559 | if (err) { | 559 | if (err) { |
560 | __journal_abort_hard(journal); | 560 | journal_abort(journal, err); |
561 | continue; | 561 | continue; |
562 | } | 562 | } |
563 | 563 | ||
@@ -748,7 +748,7 @@ wait_for_iobuf: | |||
748 | err = -EIO; | 748 | err = -EIO; |
749 | 749 | ||
750 | if (err) | 750 | if (err) |
751 | __journal_abort_hard(journal); | 751 | journal_abort(journal, err); |
752 | 752 | ||
753 | /* End of a transaction! Finally, we can do checkpoint | 753 | /* End of a transaction! Finally, we can do checkpoint |
754 | processing: any buffers committed as a result of this | 754 | processing: any buffers committed as a result of this |
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index 5d9fec0b7ebd..5d14243499d4 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/kthread.h> | 35 | #include <linux/kthread.h> |
36 | #include <linux/poison.h> | 36 | #include <linux/poison.h> |
37 | #include <linux/proc_fs.h> | 37 | #include <linux/proc_fs.h> |
38 | #include <linux/debugfs.h> | ||
38 | 39 | ||
39 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
40 | #include <asm/page.h> | 41 | #include <asm/page.h> |
@@ -654,10 +655,9 @@ static journal_t * journal_init_common (void) | |||
654 | journal_t *journal; | 655 | journal_t *journal; |
655 | int err; | 656 | int err; |
656 | 657 | ||
657 | journal = kmalloc(sizeof(*journal), GFP_KERNEL); | 658 | journal = kzalloc(sizeof(*journal), GFP_KERNEL); |
658 | if (!journal) | 659 | if (!journal) |
659 | goto fail; | 660 | goto fail; |
660 | memset(journal, 0, sizeof(*journal)); | ||
661 | 661 | ||
662 | init_waitqueue_head(&journal->j_wait_transaction_locked); | 662 | init_waitqueue_head(&journal->j_wait_transaction_locked); |
663 | init_waitqueue_head(&journal->j_wait_logspace); | 663 | init_waitqueue_head(&journal->j_wait_logspace); |
@@ -1852,64 +1852,41 @@ void journal_put_journal_head(struct journal_head *jh) | |||
1852 | } | 1852 | } |
1853 | 1853 | ||
1854 | /* | 1854 | /* |
1855 | * /proc tunables | 1855 | * debugfs tunables |
1856 | */ | 1856 | */ |
1857 | #if defined(CONFIG_JBD_DEBUG) | 1857 | #ifdef CONFIG_JBD_DEBUG |
1858 | int journal_enable_debug; | ||
1859 | EXPORT_SYMBOL(journal_enable_debug); | ||
1860 | #endif | ||
1861 | 1858 | ||
1862 | #if defined(CONFIG_JBD_DEBUG) && defined(CONFIG_PROC_FS) | 1859 | u8 journal_enable_debug __read_mostly; |
1860 | EXPORT_SYMBOL(journal_enable_debug); | ||
1863 | 1861 | ||
1864 | static struct proc_dir_entry *proc_jbd_debug; | 1862 | static struct dentry *jbd_debugfs_dir; |
1863 | static struct dentry *jbd_debug; | ||
1865 | 1864 | ||
1866 | static int read_jbd_debug(char *page, char **start, off_t off, | 1865 | static void __init jbd_create_debugfs_entry(void) |
1867 | int count, int *eof, void *data) | ||
1868 | { | 1866 | { |
1869 | int ret; | 1867 | jbd_debugfs_dir = debugfs_create_dir("jbd", NULL); |
1870 | 1868 | if (jbd_debugfs_dir) | |
1871 | ret = sprintf(page + off, "%d\n", journal_enable_debug); | 1869 | jbd_debug = debugfs_create_u8("jbd-debug", S_IRUGO, |
1872 | *eof = 1; | 1870 | jbd_debugfs_dir, |
1873 | return ret; | 1871 | &journal_enable_debug); |
1874 | } | 1872 | } |
1875 | 1873 | ||
1876 | static int write_jbd_debug(struct file *file, const char __user *buffer, | 1874 | static void __exit jbd_remove_debugfs_entry(void) |
1877 | unsigned long count, void *data) | ||
1878 | { | 1875 | { |
1879 | char buf[32]; | 1876 | debugfs_remove(jbd_debug); |
1880 | 1877 | debugfs_remove(jbd_debugfs_dir); | |
1881 | if (count > ARRAY_SIZE(buf) - 1) | ||
1882 | count = ARRAY_SIZE(buf) - 1; | ||
1883 | if (copy_from_user(buf, buffer, count)) | ||
1884 | return -EFAULT; | ||
1885 | buf[ARRAY_SIZE(buf) - 1] = '\0'; | ||
1886 | journal_enable_debug = simple_strtoul(buf, NULL, 10); | ||
1887 | return count; | ||
1888 | } | 1878 | } |
1889 | 1879 | ||
1890 | #define JBD_PROC_NAME "sys/fs/jbd-debug" | 1880 | #else |
1891 | 1881 | ||
1892 | static void __init create_jbd_proc_entry(void) | 1882 | static inline void jbd_create_debugfs_entry(void) |
1893 | { | 1883 | { |
1894 | proc_jbd_debug = create_proc_entry(JBD_PROC_NAME, 0644, NULL); | ||
1895 | if (proc_jbd_debug) { | ||
1896 | /* Why is this so hard? */ | ||
1897 | proc_jbd_debug->read_proc = read_jbd_debug; | ||
1898 | proc_jbd_debug->write_proc = write_jbd_debug; | ||
1899 | } | ||
1900 | } | 1884 | } |
1901 | 1885 | ||
1902 | static void __exit remove_jbd_proc_entry(void) | 1886 | static inline void jbd_remove_debugfs_entry(void) |
1903 | { | 1887 | { |
1904 | if (proc_jbd_debug) | ||
1905 | remove_proc_entry(JBD_PROC_NAME, NULL); | ||
1906 | } | 1888 | } |
1907 | 1889 | ||
1908 | #else | ||
1909 | |||
1910 | #define create_jbd_proc_entry() do {} while (0) | ||
1911 | #define remove_jbd_proc_entry() do {} while (0) | ||
1912 | |||
1913 | #endif | 1890 | #endif |
1914 | 1891 | ||
1915 | struct kmem_cache *jbd_handle_cache; | 1892 | struct kmem_cache *jbd_handle_cache; |
@@ -1966,7 +1943,7 @@ static int __init journal_init(void) | |||
1966 | ret = journal_init_caches(); | 1943 | ret = journal_init_caches(); |
1967 | if (ret != 0) | 1944 | if (ret != 0) |
1968 | journal_destroy_caches(); | 1945 | journal_destroy_caches(); |
1969 | create_jbd_proc_entry(); | 1946 | jbd_create_debugfs_entry(); |
1970 | return ret; | 1947 | return ret; |
1971 | } | 1948 | } |
1972 | 1949 | ||
@@ -1977,7 +1954,7 @@ static void __exit journal_exit(void) | |||
1977 | if (n) | 1954 | if (n) |
1978 | printk(KERN_EMERG "JBD: leaked %d journal_heads!\n", n); | 1955 | printk(KERN_EMERG "JBD: leaked %d journal_heads!\n", n); |
1979 | #endif | 1956 | #endif |
1980 | remove_jbd_proc_entry(); | 1957 | jbd_remove_debugfs_entry(); |
1981 | journal_destroy_caches(); | 1958 | journal_destroy_caches(); |
1982 | } | 1959 | } |
1983 | 1960 | ||
diff --git a/fs/jbd/recovery.c b/fs/jbd/recovery.c index 2a5f4b833e35..c5d9694b6a2f 100644 --- a/fs/jbd/recovery.c +++ b/fs/jbd/recovery.c | |||
@@ -250,10 +250,10 @@ int journal_recover(journal_t *journal) | |||
250 | if (!err) | 250 | if (!err) |
251 | err = do_one_pass(journal, &info, PASS_REPLAY); | 251 | err = do_one_pass(journal, &info, PASS_REPLAY); |
252 | 252 | ||
253 | jbd_debug(0, "JBD: recovery, exit status %d, " | 253 | jbd_debug(1, "JBD: recovery, exit status %d, " |
254 | "recovered transactions %u to %u\n", | 254 | "recovered transactions %u to %u\n", |
255 | err, info.start_transaction, info.end_transaction); | 255 | err, info.start_transaction, info.end_transaction); |
256 | jbd_debug(0, "JBD: Replayed %d and revoked %d/%d blocks\n", | 256 | jbd_debug(1, "JBD: Replayed %d and revoked %d/%d blocks\n", |
257 | info.nr_replays, info.nr_revoke_hits, info.nr_revokes); | 257 | info.nr_replays, info.nr_revoke_hits, info.nr_revokes); |
258 | 258 | ||
259 | /* Restart the log at the next transaction ID, thus invalidating | 259 | /* Restart the log at the next transaction ID, thus invalidating |
@@ -297,7 +297,7 @@ int journal_skip_recovery(journal_t *journal) | |||
297 | #ifdef CONFIG_JBD_DEBUG | 297 | #ifdef CONFIG_JBD_DEBUG |
298 | int dropped = info.end_transaction - be32_to_cpu(sb->s_sequence); | 298 | int dropped = info.end_transaction - be32_to_cpu(sb->s_sequence); |
299 | #endif | 299 | #endif |
300 | jbd_debug(0, | 300 | jbd_debug(1, |
301 | "JBD: ignoring %d transaction%s from the journal.\n", | 301 | "JBD: ignoring %d transaction%s from the journal.\n", |
302 | dropped, (dropped == 1) ? "" : "s"); | 302 | dropped, (dropped == 1) ? "" : "s"); |
303 | journal->j_transaction_sequence = ++info.end_transaction; | 303 | journal->j_transaction_sequence = ++info.end_transaction; |
diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c index 9841b1e5af03..08ff6c7028cc 100644 --- a/fs/jbd/transaction.c +++ b/fs/jbd/transaction.c | |||
@@ -96,13 +96,12 @@ static int start_this_handle(journal_t *journal, handle_t *handle) | |||
96 | 96 | ||
97 | alloc_transaction: | 97 | alloc_transaction: |
98 | if (!journal->j_running_transaction) { | 98 | if (!journal->j_running_transaction) { |
99 | new_transaction = kmalloc(sizeof(*new_transaction), | 99 | new_transaction = kzalloc(sizeof(*new_transaction), |
100 | GFP_NOFS|__GFP_NOFAIL); | 100 | GFP_NOFS|__GFP_NOFAIL); |
101 | if (!new_transaction) { | 101 | if (!new_transaction) { |
102 | ret = -ENOMEM; | 102 | ret = -ENOMEM; |
103 | goto out; | 103 | goto out; |
104 | } | 104 | } |
105 | memset(new_transaction, 0, sizeof(*new_transaction)); | ||
106 | } | 105 | } |
107 | 106 | ||
108 | jbd_debug(3, "New handle %p going live.\n", handle); | 107 | jbd_debug(3, "New handle %p going live.\n", handle); |
diff --git a/fs/jffs2/debug.h b/fs/jffs2/debug.h index 2a49f2c51a9f..4130adabd76e 100644 --- a/fs/jffs2/debug.h +++ b/fs/jffs2/debug.h | |||
@@ -80,28 +80,28 @@ | |||
80 | #define JFFS2_ERROR(fmt, ...) \ | 80 | #define JFFS2_ERROR(fmt, ...) \ |
81 | do { \ | 81 | do { \ |
82 | printk(JFFS2_ERR_MSG_PREFIX \ | 82 | printk(JFFS2_ERR_MSG_PREFIX \ |
83 | " (%d) %s: " fmt, current->pid, \ | 83 | " (%d) %s: " fmt, task_pid_nr(current), \ |
84 | __FUNCTION__ , ##__VA_ARGS__); \ | 84 | __FUNCTION__ , ##__VA_ARGS__); \ |
85 | } while(0) | 85 | } while(0) |
86 | 86 | ||
87 | #define JFFS2_WARNING(fmt, ...) \ | 87 | #define JFFS2_WARNING(fmt, ...) \ |
88 | do { \ | 88 | do { \ |
89 | printk(JFFS2_WARN_MSG_PREFIX \ | 89 | printk(JFFS2_WARN_MSG_PREFIX \ |
90 | " (%d) %s: " fmt, current->pid, \ | 90 | " (%d) %s: " fmt, task_pid_nr(current), \ |
91 | __FUNCTION__ , ##__VA_ARGS__); \ | 91 | __FUNCTION__ , ##__VA_ARGS__); \ |
92 | } while(0) | 92 | } while(0) |
93 | 93 | ||
94 | #define JFFS2_NOTICE(fmt, ...) \ | 94 | #define JFFS2_NOTICE(fmt, ...) \ |
95 | do { \ | 95 | do { \ |
96 | printk(JFFS2_NOTICE_MSG_PREFIX \ | 96 | printk(JFFS2_NOTICE_MSG_PREFIX \ |
97 | " (%d) %s: " fmt, current->pid, \ | 97 | " (%d) %s: " fmt, task_pid_nr(current), \ |
98 | __FUNCTION__ , ##__VA_ARGS__); \ | 98 | __FUNCTION__ , ##__VA_ARGS__); \ |
99 | } while(0) | 99 | } while(0) |
100 | 100 | ||
101 | #define JFFS2_DEBUG(fmt, ...) \ | 101 | #define JFFS2_DEBUG(fmt, ...) \ |
102 | do { \ | 102 | do { \ |
103 | printk(JFFS2_DBG_MSG_PREFIX \ | 103 | printk(JFFS2_DBG_MSG_PREFIX \ |
104 | " (%d) %s: " fmt, current->pid, \ | 104 | " (%d) %s: " fmt, task_pid_nr(current), \ |
105 | __FUNCTION__ , ##__VA_ARGS__); \ | 105 | __FUNCTION__ , ##__VA_ARGS__); \ |
106 | } while(0) | 106 | } while(0) |
107 | 107 | ||
diff --git a/fs/namespace.c b/fs/namespace.c index 07daa7972591..860752998fb3 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -1411,7 +1411,7 @@ long do_mount(char *dev_name, char *dir_name, char *type_page, | |||
1411 | mnt_flags |= MNT_RELATIME; | 1411 | mnt_flags |= MNT_RELATIME; |
1412 | 1412 | ||
1413 | flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | | 1413 | flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | |
1414 | MS_NOATIME | MS_NODIRATIME | MS_RELATIME); | 1414 | MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT); |
1415 | 1415 | ||
1416 | /* ... and get the mountpoint */ | 1416 | /* ... and get the mountpoint */ |
1417 | retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd); | 1417 | retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd); |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 46934c97f8f7..d0199189924c 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -1029,13 +1029,13 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | |||
1029 | if (EX_WGATHER(exp)) { | 1029 | if (EX_WGATHER(exp)) { |
1030 | if (atomic_read(&inode->i_writecount) > 1 | 1030 | if (atomic_read(&inode->i_writecount) > 1 |
1031 | || (last_ino == inode->i_ino && last_dev == inode->i_sb->s_dev)) { | 1031 | || (last_ino == inode->i_ino && last_dev == inode->i_sb->s_dev)) { |
1032 | dprintk("nfsd: write defer %d\n", current->pid); | 1032 | dprintk("nfsd: write defer %d\n", task_pid_nr(current)); |
1033 | msleep(10); | 1033 | msleep(10); |
1034 | dprintk("nfsd: write resume %d\n", current->pid); | 1034 | dprintk("nfsd: write resume %d\n", task_pid_nr(current)); |
1035 | } | 1035 | } |
1036 | 1036 | ||
1037 | if (inode->i_state & I_DIRTY) { | 1037 | if (inode->i_state & I_DIRTY) { |
1038 | dprintk("nfsd: write sync %d\n", current->pid); | 1038 | dprintk("nfsd: write sync %d\n", task_pid_nr(current)); |
1039 | host_err=nfsd_sync(file); | 1039 | host_err=nfsd_sync(file); |
1040 | } | 1040 | } |
1041 | #if 0 | 1041 | #if 0 |
diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index f14b541fab95..9cc7c0418b70 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c | |||
@@ -1372,7 +1372,7 @@ static ssize_t o2hb_region_pid_read(struct o2hb_region *reg, | |||
1372 | 1372 | ||
1373 | spin_lock(&o2hb_live_lock); | 1373 | spin_lock(&o2hb_live_lock); |
1374 | if (reg->hr_task) | 1374 | if (reg->hr_task) |
1375 | pid = reg->hr_task->pid; | 1375 | pid = task_pid_nr(reg->hr_task); |
1376 | spin_unlock(&o2hb_live_lock); | 1376 | spin_unlock(&o2hb_live_lock); |
1377 | 1377 | ||
1378 | if (!pid) | 1378 | if (!pid) |
diff --git a/fs/ocfs2/cluster/masklog.h b/fs/ocfs2/cluster/masklog.h index 75cd877f6d42..cd046060114e 100644 --- a/fs/ocfs2/cluster/masklog.h +++ b/fs/ocfs2/cluster/masklog.h | |||
@@ -192,7 +192,7 @@ extern struct mlog_bits mlog_and_bits, mlog_not_bits; | |||
192 | * previous token if args expands to nothing. | 192 | * previous token if args expands to nothing. |
193 | */ | 193 | */ |
194 | #define __mlog_printk(level, fmt, args...) \ | 194 | #define __mlog_printk(level, fmt, args...) \ |
195 | printk(level "(%u,%lu):%s:%d " fmt, current->pid, \ | 195 | printk(level "(%u,%lu):%s:%d " fmt, task_pid_nr(current), \ |
196 | __mlog_cpu_guess, __PRETTY_FUNCTION__, __LINE__ , \ | 196 | __mlog_cpu_guess, __PRETTY_FUNCTION__, __LINE__ , \ |
197 | ##args) | 197 | ##args) |
198 | 198 | ||
diff --git a/fs/ocfs2/dlm/dlmrecovery.c b/fs/ocfs2/dlm/dlmrecovery.c index a2c33160bfd6..2fde7bf91434 100644 --- a/fs/ocfs2/dlm/dlmrecovery.c +++ b/fs/ocfs2/dlm/dlmrecovery.c | |||
@@ -259,7 +259,7 @@ static void dlm_print_reco_node_status(struct dlm_ctxt *dlm) | |||
259 | struct dlm_lock_resource *res; | 259 | struct dlm_lock_resource *res; |
260 | 260 | ||
261 | mlog(ML_NOTICE, "%s(%d): recovery info, state=%s, dead=%u, master=%u\n", | 261 | mlog(ML_NOTICE, "%s(%d): recovery info, state=%s, dead=%u, master=%u\n", |
262 | dlm->name, dlm->dlm_reco_thread_task->pid, | 262 | dlm->name, task_pid_nr(dlm->dlm_reco_thread_task), |
263 | dlm->reco.state & DLM_RECO_STATE_ACTIVE ? "ACTIVE" : "inactive", | 263 | dlm->reco.state & DLM_RECO_STATE_ACTIVE ? "ACTIVE" : "inactive", |
264 | dlm->reco.dead_node, dlm->reco.new_master); | 264 | dlm->reco.dead_node, dlm->reco.new_master); |
265 | 265 | ||
@@ -420,7 +420,7 @@ void dlm_wait_for_recovery(struct dlm_ctxt *dlm) | |||
420 | if (dlm_in_recovery(dlm)) { | 420 | if (dlm_in_recovery(dlm)) { |
421 | mlog(0, "%s: reco thread %d in recovery: " | 421 | mlog(0, "%s: reco thread %d in recovery: " |
422 | "state=%d, master=%u, dead=%u\n", | 422 | "state=%d, master=%u, dead=%u\n", |
423 | dlm->name, dlm->dlm_reco_thread_task->pid, | 423 | dlm->name, task_pid_nr(dlm->dlm_reco_thread_task), |
424 | dlm->reco.state, dlm->reco.new_master, | 424 | dlm->reco.state, dlm->reco.new_master, |
425 | dlm->reco.dead_node); | 425 | dlm->reco.dead_node); |
426 | } | 426 | } |
@@ -483,7 +483,7 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm) | |||
483 | return 0; | 483 | return 0; |
484 | } | 484 | } |
485 | mlog(0, "%s(%d):recovery thread found node %u in the recovery map!\n", | 485 | mlog(0, "%s(%d):recovery thread found node %u in the recovery map!\n", |
486 | dlm->name, dlm->dlm_reco_thread_task->pid, | 486 | dlm->name, task_pid_nr(dlm->dlm_reco_thread_task), |
487 | dlm->reco.dead_node); | 487 | dlm->reco.dead_node); |
488 | spin_unlock(&dlm->spinlock); | 488 | spin_unlock(&dlm->spinlock); |
489 | 489 | ||
@@ -507,7 +507,7 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm) | |||
507 | mlog(0, "another node will master this recovery session.\n"); | 507 | mlog(0, "another node will master this recovery session.\n"); |
508 | } | 508 | } |
509 | mlog(0, "dlm=%s (%d), new_master=%u, this node=%u, dead_node=%u\n", | 509 | mlog(0, "dlm=%s (%d), new_master=%u, this node=%u, dead_node=%u\n", |
510 | dlm->name, dlm->dlm_reco_thread_task->pid, dlm->reco.new_master, | 510 | dlm->name, task_pid_nr(dlm->dlm_reco_thread_task), dlm->reco.new_master, |
511 | dlm->node_num, dlm->reco.dead_node); | 511 | dlm->node_num, dlm->reco.dead_node); |
512 | 512 | ||
513 | /* it is safe to start everything back up here | 513 | /* it is safe to start everything back up here |
@@ -520,7 +520,7 @@ static int dlm_do_recovery(struct dlm_ctxt *dlm) | |||
520 | 520 | ||
521 | master_here: | 521 | master_here: |
522 | mlog(0, "(%d) mastering recovery of %s:%u here(this=%u)!\n", | 522 | mlog(0, "(%d) mastering recovery of %s:%u here(this=%u)!\n", |
523 | dlm->dlm_reco_thread_task->pid, | 523 | task_pid_nr(dlm->dlm_reco_thread_task), |
524 | dlm->name, dlm->reco.dead_node, dlm->node_num); | 524 | dlm->name, dlm->reco.dead_node, dlm->node_num); |
525 | 525 | ||
526 | status = dlm_remaster_locks(dlm, dlm->reco.dead_node); | 526 | status = dlm_remaster_locks(dlm, dlm->reco.dead_node); |
diff --git a/fs/proc/array.c b/fs/proc/array.c index 27b59f5f3bd1..63c95afb561f 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
@@ -77,6 +77,7 @@ | |||
77 | #include <linux/cpuset.h> | 77 | #include <linux/cpuset.h> |
78 | #include <linux/rcupdate.h> | 78 | #include <linux/rcupdate.h> |
79 | #include <linux/delayacct.h> | 79 | #include <linux/delayacct.h> |
80 | #include <linux/pid_namespace.h> | ||
80 | 81 | ||
81 | #include <asm/pgtable.h> | 82 | #include <asm/pgtable.h> |
82 | #include <asm/processor.h> | 83 | #include <asm/processor.h> |
@@ -145,8 +146,7 @@ static inline const char *get_task_state(struct task_struct *tsk) | |||
145 | TASK_UNINTERRUPTIBLE | | 146 | TASK_UNINTERRUPTIBLE | |
146 | TASK_STOPPED | | 147 | TASK_STOPPED | |
147 | TASK_TRACED)) | | 148 | TASK_TRACED)) | |
148 | (tsk->exit_state & (EXIT_ZOMBIE | | 149 | tsk->exit_state; |
149 | EXIT_DEAD)); | ||
150 | const char **p = &task_state_array[0]; | 150 | const char **p = &task_state_array[0]; |
151 | 151 | ||
152 | while (state) { | 152 | while (state) { |
@@ -161,8 +161,15 @@ static inline char *task_state(struct task_struct *p, char *buffer) | |||
161 | struct group_info *group_info; | 161 | struct group_info *group_info; |
162 | int g; | 162 | int g; |
163 | struct fdtable *fdt = NULL; | 163 | struct fdtable *fdt = NULL; |
164 | struct pid_namespace *ns; | ||
165 | pid_t ppid, tpid; | ||
164 | 166 | ||
167 | ns = current->nsproxy->pid_ns; | ||
165 | rcu_read_lock(); | 168 | rcu_read_lock(); |
169 | ppid = pid_alive(p) ? | ||
170 | task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0; | ||
171 | tpid = pid_alive(p) && p->ptrace ? | ||
172 | task_ppid_nr_ns(rcu_dereference(p->parent), ns) : 0; | ||
166 | buffer += sprintf(buffer, | 173 | buffer += sprintf(buffer, |
167 | "State:\t%s\n" | 174 | "State:\t%s\n" |
168 | "Tgid:\t%d\n" | 175 | "Tgid:\t%d\n" |
@@ -172,9 +179,9 @@ static inline char *task_state(struct task_struct *p, char *buffer) | |||
172 | "Uid:\t%d\t%d\t%d\t%d\n" | 179 | "Uid:\t%d\t%d\t%d\t%d\n" |
173 | "Gid:\t%d\t%d\t%d\t%d\n", | 180 | "Gid:\t%d\t%d\t%d\t%d\n", |
174 | get_task_state(p), | 181 | get_task_state(p), |
175 | p->tgid, p->pid, | 182 | task_tgid_nr_ns(p, ns), |
176 | pid_alive(p) ? rcu_dereference(p->real_parent)->tgid : 0, | 183 | task_pid_nr_ns(p, ns), |
177 | pid_alive(p) && p->ptrace ? rcu_dereference(p->parent)->pid : 0, | 184 | ppid, tpid, |
178 | p->uid, p->euid, p->suid, p->fsuid, | 185 | p->uid, p->euid, p->suid, p->fsuid, |
179 | p->gid, p->egid, p->sgid, p->fsgid); | 186 | p->gid, p->egid, p->sgid, p->fsgid); |
180 | 187 | ||
@@ -394,6 +401,9 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole) | |||
394 | unsigned long rsslim = 0; | 401 | unsigned long rsslim = 0; |
395 | char tcomm[sizeof(task->comm)]; | 402 | char tcomm[sizeof(task->comm)]; |
396 | unsigned long flags; | 403 | unsigned long flags; |
404 | struct pid_namespace *ns; | ||
405 | |||
406 | ns = current->nsproxy->pid_ns; | ||
397 | 407 | ||
398 | state = *get_task_state(task); | 408 | state = *get_task_state(task); |
399 | vsize = eip = esp = 0; | 409 | vsize = eip = esp = 0; |
@@ -416,7 +426,7 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole) | |||
416 | struct signal_struct *sig = task->signal; | 426 | struct signal_struct *sig = task->signal; |
417 | 427 | ||
418 | if (sig->tty) { | 428 | if (sig->tty) { |
419 | tty_pgrp = pid_nr(sig->tty->pgrp); | 429 | tty_pgrp = pid_nr_ns(sig->tty->pgrp, ns); |
420 | tty_nr = new_encode_dev(tty_devnum(sig->tty)); | 430 | tty_nr = new_encode_dev(tty_devnum(sig->tty)); |
421 | } | 431 | } |
422 | 432 | ||
@@ -446,12 +456,12 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole) | |||
446 | maj_flt += sig->maj_flt; | 456 | maj_flt += sig->maj_flt; |
447 | utime = cputime_add(utime, sig->utime); | 457 | utime = cputime_add(utime, sig->utime); |
448 | stime = cputime_add(stime, sig->stime); | 458 | stime = cputime_add(stime, sig->stime); |
449 | gtime += cputime_add(gtime, sig->gtime); | 459 | gtime = cputime_add(gtime, sig->gtime); |
450 | } | 460 | } |
451 | 461 | ||
452 | sid = signal_session(sig); | 462 | sid = task_session_nr_ns(task, ns); |
453 | pgid = process_group(task); | 463 | pgid = task_pgrp_nr_ns(task, ns); |
454 | ppid = rcu_dereference(task->real_parent)->tgid; | 464 | ppid = task_ppid_nr_ns(task, ns); |
455 | 465 | ||
456 | unlock_task_sighand(task, &flags); | 466 | unlock_task_sighand(task, &flags); |
457 | } | 467 | } |
@@ -483,7 +493,7 @@ static int do_task_stat(struct task_struct *task, char *buffer, int whole) | |||
483 | res = sprintf(buffer, "%d (%s) %c %d %d %d %d %d %u %lu \ | 493 | res = sprintf(buffer, "%d (%s) %c %d %d %d %d %d %u %lu \ |
484 | %lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \ | 494 | %lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \ |
485 | %lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld\n", | 495 | %lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld\n", |
486 | task->pid, | 496 | task_pid_nr_ns(task, ns), |
487 | tcomm, | 497 | tcomm, |
488 | state, | 498 | state, |
489 | ppid, | 499 | ppid, |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 4fe74d156416..39a3d7c969c5 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -63,16 +63,19 @@ | |||
63 | #include <linux/mm.h> | 63 | #include <linux/mm.h> |
64 | #include <linux/rcupdate.h> | 64 | #include <linux/rcupdate.h> |
65 | #include <linux/kallsyms.h> | 65 | #include <linux/kallsyms.h> |
66 | #include <linux/resource.h> | ||
66 | #include <linux/module.h> | 67 | #include <linux/module.h> |
67 | #include <linux/mount.h> | 68 | #include <linux/mount.h> |
68 | #include <linux/security.h> | 69 | #include <linux/security.h> |
69 | #include <linux/ptrace.h> | 70 | #include <linux/ptrace.h> |
71 | #include <linux/cgroup.h> | ||
70 | #include <linux/cpuset.h> | 72 | #include <linux/cpuset.h> |
71 | #include <linux/audit.h> | 73 | #include <linux/audit.h> |
72 | #include <linux/poll.h> | 74 | #include <linux/poll.h> |
73 | #include <linux/nsproxy.h> | 75 | #include <linux/nsproxy.h> |
74 | #include <linux/oom.h> | 76 | #include <linux/oom.h> |
75 | #include <linux/elf.h> | 77 | #include <linux/elf.h> |
78 | #include <linux/pid_namespace.h> | ||
76 | #include "internal.h" | 79 | #include "internal.h" |
77 | 80 | ||
78 | /* NOTE: | 81 | /* NOTE: |
@@ -301,6 +304,78 @@ static int proc_oom_score(struct task_struct *task, char *buffer) | |||
301 | return sprintf(buffer, "%lu\n", points); | 304 | return sprintf(buffer, "%lu\n", points); |
302 | } | 305 | } |
303 | 306 | ||
307 | struct limit_names { | ||
308 | char *name; | ||
309 | char *unit; | ||
310 | }; | ||
311 | |||
312 | static const struct limit_names lnames[RLIM_NLIMITS] = { | ||
313 | [RLIMIT_CPU] = {"Max cpu time", "ms"}, | ||
314 | [RLIMIT_FSIZE] = {"Max file size", "bytes"}, | ||
315 | [RLIMIT_DATA] = {"Max data size", "bytes"}, | ||
316 | [RLIMIT_STACK] = {"Max stack size", "bytes"}, | ||
317 | [RLIMIT_CORE] = {"Max core file size", "bytes"}, | ||
318 | [RLIMIT_RSS] = {"Max resident set", "bytes"}, | ||
319 | [RLIMIT_NPROC] = {"Max processes", "processes"}, | ||
320 | [RLIMIT_NOFILE] = {"Max open files", "files"}, | ||
321 | [RLIMIT_MEMLOCK] = {"Max locked memory", "bytes"}, | ||
322 | [RLIMIT_AS] = {"Max address space", "bytes"}, | ||
323 | [RLIMIT_LOCKS] = {"Max file locks", "locks"}, | ||
324 | [RLIMIT_SIGPENDING] = {"Max pending signals", "signals"}, | ||
325 | [RLIMIT_MSGQUEUE] = {"Max msgqueue size", "bytes"}, | ||
326 | [RLIMIT_NICE] = {"Max nice priority", NULL}, | ||
327 | [RLIMIT_RTPRIO] = {"Max realtime priority", NULL}, | ||
328 | }; | ||
329 | |||
330 | /* Display limits for a process */ | ||
331 | static int proc_pid_limits(struct task_struct *task, char *buffer) | ||
332 | { | ||
333 | unsigned int i; | ||
334 | int count = 0; | ||
335 | unsigned long flags; | ||
336 | char *bufptr = buffer; | ||
337 | |||
338 | struct rlimit rlim[RLIM_NLIMITS]; | ||
339 | |||
340 | rcu_read_lock(); | ||
341 | if (!lock_task_sighand(task,&flags)) { | ||
342 | rcu_read_unlock(); | ||
343 | return 0; | ||
344 | } | ||
345 | memcpy(rlim, task->signal->rlim, sizeof(struct rlimit) * RLIM_NLIMITS); | ||
346 | unlock_task_sighand(task, &flags); | ||
347 | rcu_read_unlock(); | ||
348 | |||
349 | /* | ||
350 | * print the file header | ||
351 | */ | ||
352 | count += sprintf(&bufptr[count], "%-25s %-20s %-20s %-10s\n", | ||
353 | "Limit", "Soft Limit", "Hard Limit", "Units"); | ||
354 | |||
355 | for (i = 0; i < RLIM_NLIMITS; i++) { | ||
356 | if (rlim[i].rlim_cur == RLIM_INFINITY) | ||
357 | count += sprintf(&bufptr[count], "%-25s %-20s ", | ||
358 | lnames[i].name, "unlimited"); | ||
359 | else | ||
360 | count += sprintf(&bufptr[count], "%-25s %-20lu ", | ||
361 | lnames[i].name, rlim[i].rlim_cur); | ||
362 | |||
363 | if (rlim[i].rlim_max == RLIM_INFINITY) | ||
364 | count += sprintf(&bufptr[count], "%-20s ", "unlimited"); | ||
365 | else | ||
366 | count += sprintf(&bufptr[count], "%-20lu ", | ||
367 | rlim[i].rlim_max); | ||
368 | |||
369 | if (lnames[i].unit) | ||
370 | count += sprintf(&bufptr[count], "%-10s\n", | ||
371 | lnames[i].unit); | ||
372 | else | ||
373 | count += sprintf(&bufptr[count], "\n"); | ||
374 | } | ||
375 | |||
376 | return count; | ||
377 | } | ||
378 | |||
304 | /************************************************************************/ | 379 | /************************************************************************/ |
305 | /* Here the fs part begins */ | 380 | /* Here the fs part begins */ |
306 | /************************************************************************/ | 381 | /************************************************************************/ |
@@ -349,18 +424,21 @@ struct proc_mounts { | |||
349 | static int mounts_open(struct inode *inode, struct file *file) | 424 | static int mounts_open(struct inode *inode, struct file *file) |
350 | { | 425 | { |
351 | struct task_struct *task = get_proc_task(inode); | 426 | struct task_struct *task = get_proc_task(inode); |
427 | struct nsproxy *nsp; | ||
352 | struct mnt_namespace *ns = NULL; | 428 | struct mnt_namespace *ns = NULL; |
353 | struct proc_mounts *p; | 429 | struct proc_mounts *p; |
354 | int ret = -EINVAL; | 430 | int ret = -EINVAL; |
355 | 431 | ||
356 | if (task) { | 432 | if (task) { |
357 | task_lock(task); | 433 | rcu_read_lock(); |
358 | if (task->nsproxy) { | 434 | nsp = task_nsproxy(task); |
359 | ns = task->nsproxy->mnt_ns; | 435 | if (nsp) { |
436 | ns = nsp->mnt_ns; | ||
360 | if (ns) | 437 | if (ns) |
361 | get_mnt_ns(ns); | 438 | get_mnt_ns(ns); |
362 | } | 439 | } |
363 | task_unlock(task); | 440 | rcu_read_unlock(); |
441 | |||
364 | put_task_struct(task); | 442 | put_task_struct(task); |
365 | } | 443 | } |
366 | 444 | ||
@@ -423,16 +501,20 @@ static int mountstats_open(struct inode *inode, struct file *file) | |||
423 | 501 | ||
424 | if (!ret) { | 502 | if (!ret) { |
425 | struct seq_file *m = file->private_data; | 503 | struct seq_file *m = file->private_data; |
504 | struct nsproxy *nsp; | ||
426 | struct mnt_namespace *mnt_ns = NULL; | 505 | struct mnt_namespace *mnt_ns = NULL; |
427 | struct task_struct *task = get_proc_task(inode); | 506 | struct task_struct *task = get_proc_task(inode); |
428 | 507 | ||
429 | if (task) { | 508 | if (task) { |
430 | task_lock(task); | 509 | rcu_read_lock(); |
431 | if (task->nsproxy) | 510 | nsp = task_nsproxy(task); |
432 | mnt_ns = task->nsproxy->mnt_ns; | 511 | if (nsp) { |
433 | if (mnt_ns) | 512 | mnt_ns = nsp->mnt_ns; |
434 | get_mnt_ns(mnt_ns); | 513 | if (mnt_ns) |
435 | task_unlock(task); | 514 | get_mnt_ns(mnt_ns); |
515 | } | ||
516 | rcu_read_unlock(); | ||
517 | |||
436 | put_task_struct(task); | 518 | put_task_struct(task); |
437 | } | 519 | } |
438 | 520 | ||
@@ -1437,7 +1519,7 @@ static int proc_readfd_common(struct file * filp, void * dirent, | |||
1437 | struct dentry *dentry = filp->f_path.dentry; | 1519 | struct dentry *dentry = filp->f_path.dentry; |
1438 | struct inode *inode = dentry->d_inode; | 1520 | struct inode *inode = dentry->d_inode; |
1439 | struct task_struct *p = get_proc_task(inode); | 1521 | struct task_struct *p = get_proc_task(inode); |
1440 | unsigned int fd, tid, ino; | 1522 | unsigned int fd, ino; |
1441 | int retval; | 1523 | int retval; |
1442 | struct files_struct * files; | 1524 | struct files_struct * files; |
1443 | struct fdtable *fdt; | 1525 | struct fdtable *fdt; |
@@ -1446,7 +1528,6 @@ static int proc_readfd_common(struct file * filp, void * dirent, | |||
1446 | if (!p) | 1528 | if (!p) |
1447 | goto out_no_task; | 1529 | goto out_no_task; |
1448 | retval = 0; | 1530 | retval = 0; |
1449 | tid = p->pid; | ||
1450 | 1531 | ||
1451 | fd = filp->f_pos; | 1532 | fd = filp->f_pos; |
1452 | switch (fd) { | 1533 | switch (fd) { |
@@ -1681,7 +1762,6 @@ static int proc_pident_readdir(struct file *filp, | |||
1681 | const struct pid_entry *ents, unsigned int nents) | 1762 | const struct pid_entry *ents, unsigned int nents) |
1682 | { | 1763 | { |
1683 | int i; | 1764 | int i; |
1684 | int pid; | ||
1685 | struct dentry *dentry = filp->f_path.dentry; | 1765 | struct dentry *dentry = filp->f_path.dentry; |
1686 | struct inode *inode = dentry->d_inode; | 1766 | struct inode *inode = dentry->d_inode; |
1687 | struct task_struct *task = get_proc_task(inode); | 1767 | struct task_struct *task = get_proc_task(inode); |
@@ -1694,7 +1774,6 @@ static int proc_pident_readdir(struct file *filp, | |||
1694 | goto out_no_task; | 1774 | goto out_no_task; |
1695 | 1775 | ||
1696 | ret = 0; | 1776 | ret = 0; |
1697 | pid = task->pid; | ||
1698 | i = filp->f_pos; | 1777 | i = filp->f_pos; |
1699 | switch (i) { | 1778 | switch (i) { |
1700 | case 0: | 1779 | case 0: |
@@ -1928,14 +2007,14 @@ static int proc_self_readlink(struct dentry *dentry, char __user *buffer, | |||
1928 | int buflen) | 2007 | int buflen) |
1929 | { | 2008 | { |
1930 | char tmp[PROC_NUMBUF]; | 2009 | char tmp[PROC_NUMBUF]; |
1931 | sprintf(tmp, "%d", current->tgid); | 2010 | sprintf(tmp, "%d", task_tgid_vnr(current)); |
1932 | return vfs_readlink(dentry,buffer,buflen,tmp); | 2011 | return vfs_readlink(dentry,buffer,buflen,tmp); |
1933 | } | 2012 | } |
1934 | 2013 | ||
1935 | static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) | 2014 | static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd) |
1936 | { | 2015 | { |
1937 | char tmp[PROC_NUMBUF]; | 2016 | char tmp[PROC_NUMBUF]; |
1938 | sprintf(tmp, "%d", current->tgid); | 2017 | sprintf(tmp, "%d", task_tgid_vnr(current)); |
1939 | return ERR_PTR(vfs_follow_link(nd,tmp)); | 2018 | return ERR_PTR(vfs_follow_link(nd,tmp)); |
1940 | } | 2019 | } |
1941 | 2020 | ||
@@ -2101,6 +2180,7 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
2101 | REG("environ", S_IRUSR, environ), | 2180 | REG("environ", S_IRUSR, environ), |
2102 | INF("auxv", S_IRUSR, pid_auxv), | 2181 | INF("auxv", S_IRUSR, pid_auxv), |
2103 | INF("status", S_IRUGO, pid_status), | 2182 | INF("status", S_IRUGO, pid_status), |
2183 | INF("limits", S_IRUSR, pid_limits), | ||
2104 | #ifdef CONFIG_SCHED_DEBUG | 2184 | #ifdef CONFIG_SCHED_DEBUG |
2105 | REG("sched", S_IRUGO|S_IWUSR, pid_sched), | 2185 | REG("sched", S_IRUGO|S_IWUSR, pid_sched), |
2106 | #endif | 2186 | #endif |
@@ -2130,9 +2210,12 @@ static const struct pid_entry tgid_base_stuff[] = { | |||
2130 | #ifdef CONFIG_SCHEDSTATS | 2210 | #ifdef CONFIG_SCHEDSTATS |
2131 | INF("schedstat", S_IRUGO, pid_schedstat), | 2211 | INF("schedstat", S_IRUGO, pid_schedstat), |
2132 | #endif | 2212 | #endif |
2133 | #ifdef CONFIG_CPUSETS | 2213 | #ifdef CONFIG_PROC_PID_CPUSET |
2134 | REG("cpuset", S_IRUGO, cpuset), | 2214 | REG("cpuset", S_IRUGO, cpuset), |
2135 | #endif | 2215 | #endif |
2216 | #ifdef CONFIG_CGROUPS | ||
2217 | REG("cgroup", S_IRUGO, cgroup), | ||
2218 | #endif | ||
2136 | INF("oom_score", S_IRUGO, oom_score), | 2219 | INF("oom_score", S_IRUGO, oom_score), |
2137 | REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust), | 2220 | REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust), |
2138 | #ifdef CONFIG_AUDITSYSCALL | 2221 | #ifdef CONFIG_AUDITSYSCALL |
@@ -2193,27 +2276,27 @@ static const struct inode_operations proc_tgid_base_inode_operations = { | |||
2193 | * that no dcache entries will exist at process exit time it | 2276 | * that no dcache entries will exist at process exit time it |
2194 | * just makes it very unlikely that any will persist. | 2277 | * just makes it very unlikely that any will persist. |
2195 | */ | 2278 | */ |
2196 | void proc_flush_task(struct task_struct *task) | 2279 | static void proc_flush_task_mnt(struct vfsmount *mnt, pid_t pid, pid_t tgid) |
2197 | { | 2280 | { |
2198 | struct dentry *dentry, *leader, *dir; | 2281 | struct dentry *dentry, *leader, *dir; |
2199 | char buf[PROC_NUMBUF]; | 2282 | char buf[PROC_NUMBUF]; |
2200 | struct qstr name; | 2283 | struct qstr name; |
2201 | 2284 | ||
2202 | name.name = buf; | 2285 | name.name = buf; |
2203 | name.len = snprintf(buf, sizeof(buf), "%d", task->pid); | 2286 | name.len = snprintf(buf, sizeof(buf), "%d", pid); |
2204 | dentry = d_hash_and_lookup(proc_mnt->mnt_root, &name); | 2287 | dentry = d_hash_and_lookup(mnt->mnt_root, &name); |
2205 | if (dentry) { | 2288 | if (dentry) { |
2206 | shrink_dcache_parent(dentry); | 2289 | shrink_dcache_parent(dentry); |
2207 | d_drop(dentry); | 2290 | d_drop(dentry); |
2208 | dput(dentry); | 2291 | dput(dentry); |
2209 | } | 2292 | } |
2210 | 2293 | ||
2211 | if (thread_group_leader(task)) | 2294 | if (tgid == 0) |
2212 | goto out; | 2295 | goto out; |
2213 | 2296 | ||
2214 | name.name = buf; | 2297 | name.name = buf; |
2215 | name.len = snprintf(buf, sizeof(buf), "%d", task->tgid); | 2298 | name.len = snprintf(buf, sizeof(buf), "%d", tgid); |
2216 | leader = d_hash_and_lookup(proc_mnt->mnt_root, &name); | 2299 | leader = d_hash_and_lookup(mnt->mnt_root, &name); |
2217 | if (!leader) | 2300 | if (!leader) |
2218 | goto out; | 2301 | goto out; |
2219 | 2302 | ||
@@ -2224,7 +2307,7 @@ void proc_flush_task(struct task_struct *task) | |||
2224 | goto out_put_leader; | 2307 | goto out_put_leader; |
2225 | 2308 | ||
2226 | name.name = buf; | 2309 | name.name = buf; |
2227 | name.len = snprintf(buf, sizeof(buf), "%d", task->pid); | 2310 | name.len = snprintf(buf, sizeof(buf), "%d", pid); |
2228 | dentry = d_hash_and_lookup(dir, &name); | 2311 | dentry = d_hash_and_lookup(dir, &name); |
2229 | if (dentry) { | 2312 | if (dentry) { |
2230 | shrink_dcache_parent(dentry); | 2313 | shrink_dcache_parent(dentry); |
@@ -2239,6 +2322,36 @@ out: | |||
2239 | return; | 2322 | return; |
2240 | } | 2323 | } |
2241 | 2324 | ||
2325 | /* | ||
2326 | * when flushing dentries from proc one need to flush them from global | ||
2327 | * proc (proc_mnt) and from all the namespaces' procs this task was seen | ||
2328 | * in. this call is supposed to make all this job. | ||
2329 | */ | ||
2330 | |||
2331 | void proc_flush_task(struct task_struct *task) | ||
2332 | { | ||
2333 | int i, leader; | ||
2334 | struct pid *pid, *tgid; | ||
2335 | struct upid *upid; | ||
2336 | |||
2337 | leader = thread_group_leader(task); | ||
2338 | proc_flush_task_mnt(proc_mnt, task->pid, leader ? task->tgid : 0); | ||
2339 | pid = task_pid(task); | ||
2340 | if (pid->level == 0) | ||
2341 | return; | ||
2342 | |||
2343 | tgid = task_tgid(task); | ||
2344 | for (i = 1; i <= pid->level; i++) { | ||
2345 | upid = &pid->numbers[i]; | ||
2346 | proc_flush_task_mnt(upid->ns->proc_mnt, upid->nr, | ||
2347 | leader ? 0 : tgid->numbers[i].nr); | ||
2348 | } | ||
2349 | |||
2350 | upid = &pid->numbers[pid->level]; | ||
2351 | if (upid->nr == 1) | ||
2352 | pid_ns_release_proc(upid->ns); | ||
2353 | } | ||
2354 | |||
2242 | static struct dentry *proc_pid_instantiate(struct inode *dir, | 2355 | static struct dentry *proc_pid_instantiate(struct inode *dir, |
2243 | struct dentry * dentry, | 2356 | struct dentry * dentry, |
2244 | struct task_struct *task, const void *ptr) | 2357 | struct task_struct *task, const void *ptr) |
@@ -2274,6 +2387,7 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct | |||
2274 | struct dentry *result = ERR_PTR(-ENOENT); | 2387 | struct dentry *result = ERR_PTR(-ENOENT); |
2275 | struct task_struct *task; | 2388 | struct task_struct *task; |
2276 | unsigned tgid; | 2389 | unsigned tgid; |
2390 | struct pid_namespace *ns; | ||
2277 | 2391 | ||
2278 | result = proc_base_lookup(dir, dentry); | 2392 | result = proc_base_lookup(dir, dentry); |
2279 | if (!IS_ERR(result) || PTR_ERR(result) != -ENOENT) | 2393 | if (!IS_ERR(result) || PTR_ERR(result) != -ENOENT) |
@@ -2283,8 +2397,9 @@ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct | |||
2283 | if (tgid == ~0U) | 2397 | if (tgid == ~0U) |
2284 | goto out; | 2398 | goto out; |
2285 | 2399 | ||
2400 | ns = dentry->d_sb->s_fs_info; | ||
2286 | rcu_read_lock(); | 2401 | rcu_read_lock(); |
2287 | task = find_task_by_pid(tgid); | 2402 | task = find_task_by_pid_ns(tgid, ns); |
2288 | if (task) | 2403 | if (task) |
2289 | get_task_struct(task); | 2404 | get_task_struct(task); |
2290 | rcu_read_unlock(); | 2405 | rcu_read_unlock(); |
@@ -2301,7 +2416,8 @@ out: | |||
2301 | * Find the first task with tgid >= tgid | 2416 | * Find the first task with tgid >= tgid |
2302 | * | 2417 | * |
2303 | */ | 2418 | */ |
2304 | static struct task_struct *next_tgid(unsigned int tgid) | 2419 | static struct task_struct *next_tgid(unsigned int tgid, |
2420 | struct pid_namespace *ns) | ||
2305 | { | 2421 | { |
2306 | struct task_struct *task; | 2422 | struct task_struct *task; |
2307 | struct pid *pid; | 2423 | struct pid *pid; |
@@ -2309,9 +2425,9 @@ static struct task_struct *next_tgid(unsigned int tgid) | |||
2309 | rcu_read_lock(); | 2425 | rcu_read_lock(); |
2310 | retry: | 2426 | retry: |
2311 | task = NULL; | 2427 | task = NULL; |
2312 | pid = find_ge_pid(tgid); | 2428 | pid = find_ge_pid(tgid, ns); |
2313 | if (pid) { | 2429 | if (pid) { |
2314 | tgid = pid->nr + 1; | 2430 | tgid = pid_nr_ns(pid, ns) + 1; |
2315 | task = pid_task(pid, PIDTYPE_PID); | 2431 | task = pid_task(pid, PIDTYPE_PID); |
2316 | /* What we to know is if the pid we have find is the | 2432 | /* What we to know is if the pid we have find is the |
2317 | * pid of a thread_group_leader. Testing for task | 2433 | * pid of a thread_group_leader. Testing for task |
@@ -2351,6 +2467,7 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
2351 | struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode); | 2467 | struct task_struct *reaper = get_proc_task(filp->f_path.dentry->d_inode); |
2352 | struct task_struct *task; | 2468 | struct task_struct *task; |
2353 | int tgid; | 2469 | int tgid; |
2470 | struct pid_namespace *ns; | ||
2354 | 2471 | ||
2355 | if (!reaper) | 2472 | if (!reaper) |
2356 | goto out_no_task; | 2473 | goto out_no_task; |
@@ -2361,11 +2478,12 @@ int proc_pid_readdir(struct file * filp, void * dirent, filldir_t filldir) | |||
2361 | goto out; | 2478 | goto out; |
2362 | } | 2479 | } |
2363 | 2480 | ||
2481 | ns = filp->f_dentry->d_sb->s_fs_info; | ||
2364 | tgid = filp->f_pos - TGID_OFFSET; | 2482 | tgid = filp->f_pos - TGID_OFFSET; |
2365 | for (task = next_tgid(tgid); | 2483 | for (task = next_tgid(tgid, ns); |
2366 | task; | 2484 | task; |
2367 | put_task_struct(task), task = next_tgid(tgid + 1)) { | 2485 | put_task_struct(task), task = next_tgid(tgid + 1, ns)) { |
2368 | tgid = task->pid; | 2486 | tgid = task_pid_nr_ns(task, ns); |
2369 | filp->f_pos = tgid + TGID_OFFSET; | 2487 | filp->f_pos = tgid + TGID_OFFSET; |
2370 | if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) { | 2488 | if (proc_pid_fill_cache(filp, dirent, filldir, task, tgid) < 0) { |
2371 | put_task_struct(task); | 2489 | put_task_struct(task); |
@@ -2388,6 +2506,7 @@ static const struct pid_entry tid_base_stuff[] = { | |||
2388 | REG("environ", S_IRUSR, environ), | 2506 | REG("environ", S_IRUSR, environ), |
2389 | INF("auxv", S_IRUSR, pid_auxv), | 2507 | INF("auxv", S_IRUSR, pid_auxv), |
2390 | INF("status", S_IRUGO, pid_status), | 2508 | INF("status", S_IRUGO, pid_status), |
2509 | INF("limits", S_IRUSR, pid_limits), | ||
2391 | #ifdef CONFIG_SCHED_DEBUG | 2510 | #ifdef CONFIG_SCHED_DEBUG |
2392 | REG("sched", S_IRUGO|S_IWUSR, pid_sched), | 2511 | REG("sched", S_IRUGO|S_IWUSR, pid_sched), |
2393 | #endif | 2512 | #endif |
@@ -2416,9 +2535,12 @@ static const struct pid_entry tid_base_stuff[] = { | |||
2416 | #ifdef CONFIG_SCHEDSTATS | 2535 | #ifdef CONFIG_SCHEDSTATS |
2417 | INF("schedstat", S_IRUGO, pid_schedstat), | 2536 | INF("schedstat", S_IRUGO, pid_schedstat), |
2418 | #endif | 2537 | #endif |
2419 | #ifdef CONFIG_CPUSETS | 2538 | #ifdef CONFIG_PROC_PID_CPUSET |
2420 | REG("cpuset", S_IRUGO, cpuset), | 2539 | REG("cpuset", S_IRUGO, cpuset), |
2421 | #endif | 2540 | #endif |
2541 | #ifdef CONFIG_CGROUPS | ||
2542 | REG("cgroup", S_IRUGO, cgroup), | ||
2543 | #endif | ||
2422 | INF("oom_score", S_IRUGO, oom_score), | 2544 | INF("oom_score", S_IRUGO, oom_score), |
2423 | REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust), | 2545 | REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust), |
2424 | #ifdef CONFIG_AUDITSYSCALL | 2546 | #ifdef CONFIG_AUDITSYSCALL |
@@ -2486,6 +2608,7 @@ static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry | |||
2486 | struct task_struct *task; | 2608 | struct task_struct *task; |
2487 | struct task_struct *leader = get_proc_task(dir); | 2609 | struct task_struct *leader = get_proc_task(dir); |
2488 | unsigned tid; | 2610 | unsigned tid; |
2611 | struct pid_namespace *ns; | ||
2489 | 2612 | ||
2490 | if (!leader) | 2613 | if (!leader) |
2491 | goto out_no_task; | 2614 | goto out_no_task; |
@@ -2494,14 +2617,15 @@ static struct dentry *proc_task_lookup(struct inode *dir, struct dentry * dentry | |||
2494 | if (tid == ~0U) | 2617 | if (tid == ~0U) |
2495 | goto out; | 2618 | goto out; |
2496 | 2619 | ||
2620 | ns = dentry->d_sb->s_fs_info; | ||
2497 | rcu_read_lock(); | 2621 | rcu_read_lock(); |
2498 | task = find_task_by_pid(tid); | 2622 | task = find_task_by_pid_ns(tid, ns); |
2499 | if (task) | 2623 | if (task) |
2500 | get_task_struct(task); | 2624 | get_task_struct(task); |
2501 | rcu_read_unlock(); | 2625 | rcu_read_unlock(); |
2502 | if (!task) | 2626 | if (!task) |
2503 | goto out; | 2627 | goto out; |
2504 | if (leader->tgid != task->tgid) | 2628 | if (!same_thread_group(leader, task)) |
2505 | goto out_drop_task; | 2629 | goto out_drop_task; |
2506 | 2630 | ||
2507 | result = proc_task_instantiate(dir, dentry, task, NULL); | 2631 | result = proc_task_instantiate(dir, dentry, task, NULL); |
@@ -2526,14 +2650,14 @@ out_no_task: | |||
2526 | * threads past it. | 2650 | * threads past it. |
2527 | */ | 2651 | */ |
2528 | static struct task_struct *first_tid(struct task_struct *leader, | 2652 | static struct task_struct *first_tid(struct task_struct *leader, |
2529 | int tid, int nr) | 2653 | int tid, int nr, struct pid_namespace *ns) |
2530 | { | 2654 | { |
2531 | struct task_struct *pos; | 2655 | struct task_struct *pos; |
2532 | 2656 | ||
2533 | rcu_read_lock(); | 2657 | rcu_read_lock(); |
2534 | /* Attempt to start with the pid of a thread */ | 2658 | /* Attempt to start with the pid of a thread */ |
2535 | if (tid && (nr > 0)) { | 2659 | if (tid && (nr > 0)) { |
2536 | pos = find_task_by_pid(tid); | 2660 | pos = find_task_by_pid_ns(tid, ns); |
2537 | if (pos && (pos->group_leader == leader)) | 2661 | if (pos && (pos->group_leader == leader)) |
2538 | goto found; | 2662 | goto found; |
2539 | } | 2663 | } |
@@ -2602,6 +2726,7 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi | |||
2602 | ino_t ino; | 2726 | ino_t ino; |
2603 | int tid; | 2727 | int tid; |
2604 | unsigned long pos = filp->f_pos; /* avoiding "long long" filp->f_pos */ | 2728 | unsigned long pos = filp->f_pos; /* avoiding "long long" filp->f_pos */ |
2729 | struct pid_namespace *ns; | ||
2605 | 2730 | ||
2606 | task = get_proc_task(inode); | 2731 | task = get_proc_task(inode); |
2607 | if (!task) | 2732 | if (!task) |
@@ -2635,12 +2760,13 @@ static int proc_task_readdir(struct file * filp, void * dirent, filldir_t filldi | |||
2635 | /* f_version caches the tgid value that the last readdir call couldn't | 2760 | /* f_version caches the tgid value that the last readdir call couldn't |
2636 | * return. lseek aka telldir automagically resets f_version to 0. | 2761 | * return. lseek aka telldir automagically resets f_version to 0. |
2637 | */ | 2762 | */ |
2763 | ns = filp->f_dentry->d_sb->s_fs_info; | ||
2638 | tid = (int)filp->f_version; | 2764 | tid = (int)filp->f_version; |
2639 | filp->f_version = 0; | 2765 | filp->f_version = 0; |
2640 | for (task = first_tid(leader, tid, pos - 2); | 2766 | for (task = first_tid(leader, tid, pos - 2, ns); |
2641 | task; | 2767 | task; |
2642 | task = next_tid(task), pos++) { | 2768 | task = next_tid(task), pos++) { |
2643 | tid = task->pid; | 2769 | tid = task_pid_nr_ns(task, ns); |
2644 | if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) { | 2770 | if (proc_task_fill_cache(filp, dirent, filldir, task, tid) < 0) { |
2645 | /* returning this tgid failed, save it as the first | 2771 | /* returning this tgid failed, save it as the first |
2646 | * pid for the next readir call */ | 2772 | * pid for the next readir call */ |
diff --git a/fs/proc/inode.c b/fs/proc/inode.c index 99ca00485fc3..abe6a3f04368 100644 --- a/fs/proc/inode.c +++ b/fs/proc/inode.c | |||
@@ -448,7 +448,7 @@ out_mod: | |||
448 | return NULL; | 448 | return NULL; |
449 | } | 449 | } |
450 | 450 | ||
451 | int proc_fill_super(struct super_block *s, void *data, int silent) | 451 | int proc_fill_super(struct super_block *s) |
452 | { | 452 | { |
453 | struct inode * root_inode; | 453 | struct inode * root_inode; |
454 | 454 | ||
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c index d6dc72c78bc1..e0d064e9764e 100644 --- a/fs/proc/proc_misc.c +++ b/fs/proc/proc_misc.c | |||
@@ -91,7 +91,8 @@ static int loadavg_read_proc(char *page, char **start, off_t off, | |||
91 | LOAD_INT(a), LOAD_FRAC(a), | 91 | LOAD_INT(a), LOAD_FRAC(a), |
92 | LOAD_INT(b), LOAD_FRAC(b), | 92 | LOAD_INT(b), LOAD_FRAC(b), |
93 | LOAD_INT(c), LOAD_FRAC(c), | 93 | LOAD_INT(c), LOAD_FRAC(c), |
94 | nr_running(), nr_threads, current->nsproxy->pid_ns->last_pid); | 94 | nr_running(), nr_threads, |
95 | task_active_pid_ns(current)->last_pid); | ||
95 | return proc_calc_metrics(page, start, off, count, eof, len); | 96 | return proc_calc_metrics(page, start, off, count, eof, len); |
96 | } | 97 | } |
97 | 98 | ||
diff --git a/fs/proc/root.c b/fs/proc/root.c index cf3046638b09..ec9cb3b6c93b 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c | |||
@@ -18,32 +18,90 @@ | |||
18 | #include <linux/bitops.h> | 18 | #include <linux/bitops.h> |
19 | #include <linux/smp_lock.h> | 19 | #include <linux/smp_lock.h> |
20 | #include <linux/mount.h> | 20 | #include <linux/mount.h> |
21 | #include <linux/pid_namespace.h> | ||
21 | 22 | ||
22 | #include "internal.h" | 23 | #include "internal.h" |
23 | 24 | ||
24 | struct proc_dir_entry *proc_bus, *proc_root_fs, *proc_root_driver; | 25 | struct proc_dir_entry *proc_bus, *proc_root_fs, *proc_root_driver; |
25 | 26 | ||
27 | static int proc_test_super(struct super_block *sb, void *data) | ||
28 | { | ||
29 | return sb->s_fs_info == data; | ||
30 | } | ||
31 | |||
32 | static int proc_set_super(struct super_block *sb, void *data) | ||
33 | { | ||
34 | struct pid_namespace *ns; | ||
35 | |||
36 | ns = (struct pid_namespace *)data; | ||
37 | sb->s_fs_info = get_pid_ns(ns); | ||
38 | return set_anon_super(sb, NULL); | ||
39 | } | ||
40 | |||
26 | static int proc_get_sb(struct file_system_type *fs_type, | 41 | static int proc_get_sb(struct file_system_type *fs_type, |
27 | int flags, const char *dev_name, void *data, struct vfsmount *mnt) | 42 | int flags, const char *dev_name, void *data, struct vfsmount *mnt) |
28 | { | 43 | { |
44 | int err; | ||
45 | struct super_block *sb; | ||
46 | struct pid_namespace *ns; | ||
47 | struct proc_inode *ei; | ||
48 | |||
29 | if (proc_mnt) { | 49 | if (proc_mnt) { |
30 | /* Seed the root directory with a pid so it doesn't need | 50 | /* Seed the root directory with a pid so it doesn't need |
31 | * to be special in base.c. I would do this earlier but | 51 | * to be special in base.c. I would do this earlier but |
32 | * the only task alive when /proc is mounted the first time | 52 | * the only task alive when /proc is mounted the first time |
33 | * is the init_task and it doesn't have any pids. | 53 | * is the init_task and it doesn't have any pids. |
34 | */ | 54 | */ |
35 | struct proc_inode *ei; | ||
36 | ei = PROC_I(proc_mnt->mnt_sb->s_root->d_inode); | 55 | ei = PROC_I(proc_mnt->mnt_sb->s_root->d_inode); |
37 | if (!ei->pid) | 56 | if (!ei->pid) |
38 | ei->pid = find_get_pid(1); | 57 | ei->pid = find_get_pid(1); |
39 | } | 58 | } |
40 | return get_sb_single(fs_type, flags, data, proc_fill_super, mnt); | 59 | |
60 | if (flags & MS_KERNMOUNT) | ||
61 | ns = (struct pid_namespace *)data; | ||
62 | else | ||
63 | ns = current->nsproxy->pid_ns; | ||
64 | |||
65 | sb = sget(fs_type, proc_test_super, proc_set_super, ns); | ||
66 | if (IS_ERR(sb)) | ||
67 | return PTR_ERR(sb); | ||
68 | |||
69 | if (!sb->s_root) { | ||
70 | sb->s_flags = flags; | ||
71 | err = proc_fill_super(sb); | ||
72 | if (err) { | ||
73 | up_write(&sb->s_umount); | ||
74 | deactivate_super(sb); | ||
75 | return err; | ||
76 | } | ||
77 | |||
78 | ei = PROC_I(sb->s_root->d_inode); | ||
79 | if (!ei->pid) { | ||
80 | rcu_read_lock(); | ||
81 | ei->pid = get_pid(find_pid_ns(1, ns)); | ||
82 | rcu_read_unlock(); | ||
83 | } | ||
84 | |||
85 | sb->s_flags |= MS_ACTIVE; | ||
86 | ns->proc_mnt = mnt; | ||
87 | } | ||
88 | |||
89 | return simple_set_mnt(mnt, sb); | ||
90 | } | ||
91 | |||
92 | static void proc_kill_sb(struct super_block *sb) | ||
93 | { | ||
94 | struct pid_namespace *ns; | ||
95 | |||
96 | ns = (struct pid_namespace *)sb->s_fs_info; | ||
97 | kill_anon_super(sb); | ||
98 | put_pid_ns(ns); | ||
41 | } | 99 | } |
42 | 100 | ||
43 | static struct file_system_type proc_fs_type = { | 101 | static struct file_system_type proc_fs_type = { |
44 | .name = "proc", | 102 | .name = "proc", |
45 | .get_sb = proc_get_sb, | 103 | .get_sb = proc_get_sb, |
46 | .kill_sb = kill_anon_super, | 104 | .kill_sb = proc_kill_sb, |
47 | }; | 105 | }; |
48 | 106 | ||
49 | void __init proc_root_init(void) | 107 | void __init proc_root_init(void) |
@@ -54,12 +112,13 @@ void __init proc_root_init(void) | |||
54 | err = register_filesystem(&proc_fs_type); | 112 | err = register_filesystem(&proc_fs_type); |
55 | if (err) | 113 | if (err) |
56 | return; | 114 | return; |
57 | proc_mnt = kern_mount(&proc_fs_type); | 115 | proc_mnt = kern_mount_data(&proc_fs_type, &init_pid_ns); |
58 | err = PTR_ERR(proc_mnt); | 116 | err = PTR_ERR(proc_mnt); |
59 | if (IS_ERR(proc_mnt)) { | 117 | if (IS_ERR(proc_mnt)) { |
60 | unregister_filesystem(&proc_fs_type); | 118 | unregister_filesystem(&proc_fs_type); |
61 | return; | 119 | return; |
62 | } | 120 | } |
121 | |||
63 | proc_misc_init(); | 122 | proc_misc_init(); |
64 | 123 | ||
65 | proc_net_init(); | 124 | proc_net_init(); |
@@ -153,6 +212,22 @@ struct proc_dir_entry proc_root = { | |||
153 | .parent = &proc_root, | 212 | .parent = &proc_root, |
154 | }; | 213 | }; |
155 | 214 | ||
215 | int pid_ns_prepare_proc(struct pid_namespace *ns) | ||
216 | { | ||
217 | struct vfsmount *mnt; | ||
218 | |||
219 | mnt = kern_mount_data(&proc_fs_type, ns); | ||
220 | if (IS_ERR(mnt)) | ||
221 | return PTR_ERR(mnt); | ||
222 | |||
223 | return 0; | ||
224 | } | ||
225 | |||
226 | void pid_ns_release_proc(struct pid_namespace *ns) | ||
227 | { | ||
228 | mntput(ns->proc_mnt); | ||
229 | } | ||
230 | |||
156 | EXPORT_SYMBOL(proc_symlink); | 231 | EXPORT_SYMBOL(proc_symlink); |
157 | EXPORT_SYMBOL(proc_mkdir); | 232 | EXPORT_SYMBOL(proc_mkdir); |
158 | EXPORT_SYMBOL(create_proc_entry); | 233 | EXPORT_SYMBOL(create_proc_entry); |
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index 2a5dd34649b3..16b331dd9913 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c | |||
@@ -47,7 +47,9 @@ | |||
47 | test_bit(_ALLOC_ ## optname , &SB_ALLOC_OPTS(s)) | 47 | test_bit(_ALLOC_ ## optname , &SB_ALLOC_OPTS(s)) |
48 | 48 | ||
49 | static inline void get_bit_address(struct super_block *s, | 49 | static inline void get_bit_address(struct super_block *s, |
50 | b_blocknr_t block, int *bmap_nr, int *offset) | 50 | b_blocknr_t block, |
51 | unsigned int *bmap_nr, | ||
52 | unsigned int *offset) | ||
51 | { | 53 | { |
52 | /* It is in the bitmap block number equal to the block | 54 | /* It is in the bitmap block number equal to the block |
53 | * number divided by the number of bits in a block. */ | 55 | * number divided by the number of bits in a block. */ |
@@ -56,10 +58,10 @@ static inline void get_bit_address(struct super_block *s, | |||
56 | *offset = block & ((s->s_blocksize << 3) - 1); | 58 | *offset = block & ((s->s_blocksize << 3) - 1); |
57 | } | 59 | } |
58 | 60 | ||
59 | #ifdef CONFIG_REISERFS_CHECK | ||
60 | int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) | 61 | int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) |
61 | { | 62 | { |
62 | int bmap, offset; | 63 | unsigned int bmap, offset; |
64 | unsigned int bmap_count = reiserfs_bmap_count(s); | ||
63 | 65 | ||
64 | if (block == 0 || block >= SB_BLOCK_COUNT(s)) { | 66 | if (block == 0 || block >= SB_BLOCK_COUNT(s)) { |
65 | reiserfs_warning(s, | 67 | reiserfs_warning(s, |
@@ -75,25 +77,26 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) | |||
75 | if (unlikely(test_bit(REISERFS_OLD_FORMAT, | 77 | if (unlikely(test_bit(REISERFS_OLD_FORMAT, |
76 | &(REISERFS_SB(s)->s_properties)))) { | 78 | &(REISERFS_SB(s)->s_properties)))) { |
77 | b_blocknr_t bmap1 = REISERFS_SB(s)->s_sbh->b_blocknr + 1; | 79 | b_blocknr_t bmap1 = REISERFS_SB(s)->s_sbh->b_blocknr + 1; |
78 | if (block >= bmap1 && block <= bmap1 + SB_BMAP_NR(s)) { | 80 | if (block >= bmap1 && |
81 | block <= bmap1 + bmap_count) { | ||
79 | reiserfs_warning(s, "vs: 4019: is_reusable: " | 82 | reiserfs_warning(s, "vs: 4019: is_reusable: " |
80 | "bitmap block %lu(%u) can't be freed or reused", | 83 | "bitmap block %lu(%u) can't be freed or reused", |
81 | block, SB_BMAP_NR(s)); | 84 | block, bmap_count); |
82 | return 0; | 85 | return 0; |
83 | } | 86 | } |
84 | } else { | 87 | } else { |
85 | if (offset == 0) { | 88 | if (offset == 0) { |
86 | reiserfs_warning(s, "vs: 4020: is_reusable: " | 89 | reiserfs_warning(s, "vs: 4020: is_reusable: " |
87 | "bitmap block %lu(%u) can't be freed or reused", | 90 | "bitmap block %lu(%u) can't be freed or reused", |
88 | block, SB_BMAP_NR(s)); | 91 | block, bmap_count); |
89 | return 0; | 92 | return 0; |
90 | } | 93 | } |
91 | } | 94 | } |
92 | 95 | ||
93 | if (bmap >= SB_BMAP_NR(s)) { | 96 | if (bmap >= bmap_count) { |
94 | reiserfs_warning(s, | 97 | reiserfs_warning(s, |
95 | "vs-4030: is_reusable: there is no so many bitmap blocks: " | 98 | "vs-4030: is_reusable: there is no so many bitmap blocks: " |
96 | "block=%lu, bitmap_nr=%d", block, bmap); | 99 | "block=%lu, bitmap_nr=%u", block, bmap); |
97 | return 0; | 100 | return 0; |
98 | } | 101 | } |
99 | 102 | ||
@@ -106,12 +109,11 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) | |||
106 | 109 | ||
107 | return 1; | 110 | return 1; |
108 | } | 111 | } |
109 | #endif /* CONFIG_REISERFS_CHECK */ | ||
110 | 112 | ||
111 | /* searches in journal structures for a given block number (bmap, off). If block | 113 | /* searches in journal structures for a given block number (bmap, off). If block |
112 | is found in reiserfs journal it suggests next free block candidate to test. */ | 114 | is found in reiserfs journal it suggests next free block candidate to test. */ |
113 | static inline int is_block_in_journal(struct super_block *s, int bmap, int | 115 | static inline int is_block_in_journal(struct super_block *s, unsigned int bmap, |
114 | off, int *next) | 116 | int off, int *next) |
115 | { | 117 | { |
116 | b_blocknr_t tmp; | 118 | b_blocknr_t tmp; |
117 | 119 | ||
@@ -132,8 +134,8 @@ static inline int is_block_in_journal(struct super_block *s, int bmap, int | |||
132 | /* it searches for a window of zero bits with given minimum and maximum lengths in one bitmap | 134 | /* it searches for a window of zero bits with given minimum and maximum lengths in one bitmap |
133 | * block; */ | 135 | * block; */ |
134 | static int scan_bitmap_block(struct reiserfs_transaction_handle *th, | 136 | static int scan_bitmap_block(struct reiserfs_transaction_handle *th, |
135 | int bmap_n, int *beg, int boundary, int min, | 137 | unsigned int bmap_n, int *beg, int boundary, |
136 | int max, int unfm) | 138 | int min, int max, int unfm) |
137 | { | 139 | { |
138 | struct super_block *s = th->t_super; | 140 | struct super_block *s = th->t_super; |
139 | struct reiserfs_bitmap_info *bi = &SB_AP_BITMAP(s)[bmap_n]; | 141 | struct reiserfs_bitmap_info *bi = &SB_AP_BITMAP(s)[bmap_n]; |
@@ -143,8 +145,8 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th, | |||
143 | 145 | ||
144 | BUG_ON(!th->t_trans_id); | 146 | BUG_ON(!th->t_trans_id); |
145 | 147 | ||
146 | RFALSE(bmap_n >= SB_BMAP_NR(s), "Bitmap %d is out of range (0..%d)", | 148 | RFALSE(bmap_n >= reiserfs_bmap_count(s), "Bitmap %u is out of " |
147 | bmap_n, SB_BMAP_NR(s) - 1); | 149 | "range (0..%u)", bmap_n, reiserfs_bmap_count(s) - 1); |
148 | PROC_INFO_INC(s, scan_bitmap.bmap); | 150 | PROC_INFO_INC(s, scan_bitmap.bmap); |
149 | /* this is unclear and lacks comments, explain how journal bitmaps | 151 | /* this is unclear and lacks comments, explain how journal bitmaps |
150 | work here for the reader. Convey a sense of the design here. What | 152 | work here for the reader. Convey a sense of the design here. What |
@@ -249,12 +251,12 @@ static int bmap_hash_id(struct super_block *s, u32 id) | |||
249 | } else { | 251 | } else { |
250 | hash_in = (char *)(&id); | 252 | hash_in = (char *)(&id); |
251 | hash = keyed_hash(hash_in, 4); | 253 | hash = keyed_hash(hash_in, 4); |
252 | bm = hash % SB_BMAP_NR(s); | 254 | bm = hash % reiserfs_bmap_count(s); |
253 | if (!bm) | 255 | if (!bm) |
254 | bm = 1; | 256 | bm = 1; |
255 | } | 257 | } |
256 | /* this can only be true when SB_BMAP_NR = 1 */ | 258 | /* this can only be true when SB_BMAP_NR = 1 */ |
257 | if (bm >= SB_BMAP_NR(s)) | 259 | if (bm >= reiserfs_bmap_count(s)) |
258 | bm = 0; | 260 | bm = 0; |
259 | return bm; | 261 | return bm; |
260 | } | 262 | } |
@@ -273,7 +275,7 @@ static inline int block_group_used(struct super_block *s, u32 id) | |||
273 | * to make a better decision. This favors long-term performace gain | 275 | * to make a better decision. This favors long-term performace gain |
274 | * with a better on-disk layout vs. a short term gain of skipping the | 276 | * with a better on-disk layout vs. a short term gain of skipping the |
275 | * read and potentially having a bad placement. */ | 277 | * read and potentially having a bad placement. */ |
276 | if (info->first_zero_hint == 0) { | 278 | if (info->free_count == UINT_MAX) { |
277 | struct buffer_head *bh = reiserfs_read_bitmap_block(s, bm); | 279 | struct buffer_head *bh = reiserfs_read_bitmap_block(s, bm); |
278 | brelse(bh); | 280 | brelse(bh); |
279 | } | 281 | } |
@@ -309,16 +311,16 @@ __le32 reiserfs_choose_packing(struct inode * dir) | |||
309 | * bitmap and place new blocks there. Returns number of allocated blocks. */ | 311 | * bitmap and place new blocks there. Returns number of allocated blocks. */ |
310 | static int scan_bitmap(struct reiserfs_transaction_handle *th, | 312 | static int scan_bitmap(struct reiserfs_transaction_handle *th, |
311 | b_blocknr_t * start, b_blocknr_t finish, | 313 | b_blocknr_t * start, b_blocknr_t finish, |
312 | int min, int max, int unfm, unsigned long file_block) | 314 | int min, int max, int unfm, sector_t file_block) |
313 | { | 315 | { |
314 | int nr_allocated = 0; | 316 | int nr_allocated = 0; |
315 | struct super_block *s = th->t_super; | 317 | struct super_block *s = th->t_super; |
316 | /* find every bm and bmap and bmap_nr in this file, and change them all to bitmap_blocknr | 318 | /* find every bm and bmap and bmap_nr in this file, and change them all to bitmap_blocknr |
317 | * - Hans, it is not a block number - Zam. */ | 319 | * - Hans, it is not a block number - Zam. */ |
318 | 320 | ||
319 | int bm, off; | 321 | unsigned int bm, off; |
320 | int end_bm, end_off; | 322 | unsigned int end_bm, end_off; |
321 | int off_max = s->s_blocksize << 3; | 323 | unsigned int off_max = s->s_blocksize << 3; |
322 | 324 | ||
323 | BUG_ON(!th->t_trans_id); | 325 | BUG_ON(!th->t_trans_id); |
324 | 326 | ||
@@ -328,10 +330,10 @@ static int scan_bitmap(struct reiserfs_transaction_handle *th, | |||
328 | 330 | ||
329 | get_bit_address(s, *start, &bm, &off); | 331 | get_bit_address(s, *start, &bm, &off); |
330 | get_bit_address(s, finish, &end_bm, &end_off); | 332 | get_bit_address(s, finish, &end_bm, &end_off); |
331 | if (bm > SB_BMAP_NR(s)) | 333 | if (bm > reiserfs_bmap_count(s)) |
332 | return 0; | 334 | return 0; |
333 | if (end_bm > SB_BMAP_NR(s)) | 335 | if (end_bm > reiserfs_bmap_count(s)) |
334 | end_bm = SB_BMAP_NR(s); | 336 | end_bm = reiserfs_bmap_count(s); |
335 | 337 | ||
336 | /* When the bitmap is more than 10% free, anyone can allocate. | 338 | /* When the bitmap is more than 10% free, anyone can allocate. |
337 | * When it's less than 10% free, only files that already use the | 339 | * When it's less than 10% free, only files that already use the |
@@ -385,7 +387,7 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th, | |||
385 | struct reiserfs_super_block *rs; | 387 | struct reiserfs_super_block *rs; |
386 | struct buffer_head *sbh, *bmbh; | 388 | struct buffer_head *sbh, *bmbh; |
387 | struct reiserfs_bitmap_info *apbi; | 389 | struct reiserfs_bitmap_info *apbi; |
388 | int nr, offset; | 390 | unsigned int nr, offset; |
389 | 391 | ||
390 | BUG_ON(!th->t_trans_id); | 392 | BUG_ON(!th->t_trans_id); |
391 | 393 | ||
@@ -397,10 +399,12 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th, | |||
397 | 399 | ||
398 | get_bit_address(s, block, &nr, &offset); | 400 | get_bit_address(s, block, &nr, &offset); |
399 | 401 | ||
400 | if (nr >= sb_bmap_nr(rs)) { | 402 | if (nr >= reiserfs_bmap_count(s)) { |
401 | reiserfs_warning(s, "vs-4075: reiserfs_free_block: " | 403 | reiserfs_warning(s, "vs-4075: reiserfs_free_block: " |
402 | "block %lu is out of range on %s", | 404 | "block %lu is out of range on %s " |
403 | block, reiserfs_bdevname(s)); | 405 | "(nr=%u,max=%u)", block, |
406 | reiserfs_bdevname(s), nr, | ||
407 | reiserfs_bmap_count(s)); | ||
404 | return; | 408 | return; |
405 | } | 409 | } |
406 | 410 | ||
@@ -434,12 +438,19 @@ void reiserfs_free_block(struct reiserfs_transaction_handle *th, | |||
434 | int for_unformatted) | 438 | int for_unformatted) |
435 | { | 439 | { |
436 | struct super_block *s = th->t_super; | 440 | struct super_block *s = th->t_super; |
437 | |||
438 | BUG_ON(!th->t_trans_id); | 441 | BUG_ON(!th->t_trans_id); |
439 | 442 | ||
440 | RFALSE(!s, "vs-4061: trying to free block on nonexistent device"); | 443 | RFALSE(!s, "vs-4061: trying to free block on nonexistent device"); |
441 | RFALSE(is_reusable(s, block, 1) == 0, | 444 | if (!is_reusable(s, block, 1)) |
442 | "vs-4071: can not free such block"); | 445 | return; |
446 | |||
447 | if (block > sb_block_count(REISERFS_SB(s)->s_rs)) { | ||
448 | reiserfs_panic(th->t_super, "bitmap-4072", | ||
449 | "Trying to free block outside file system " | ||
450 | "boundaries (%lu > %lu)", | ||
451 | block, sb_block_count(REISERFS_SB(s)->s_rs)); | ||
452 | return; | ||
453 | } | ||
443 | /* mark it before we clear it, just in case */ | 454 | /* mark it before we clear it, just in case */ |
444 | journal_mark_freed(th, s, block); | 455 | journal_mark_freed(th, s, block); |
445 | _reiserfs_free_block(th, inode, block, for_unformatted); | 456 | _reiserfs_free_block(th, inode, block, for_unformatted); |
@@ -449,11 +460,11 @@ void reiserfs_free_block(struct reiserfs_transaction_handle *th, | |||
449 | static void reiserfs_free_prealloc_block(struct reiserfs_transaction_handle *th, | 460 | static void reiserfs_free_prealloc_block(struct reiserfs_transaction_handle *th, |
450 | struct inode *inode, b_blocknr_t block) | 461 | struct inode *inode, b_blocknr_t block) |
451 | { | 462 | { |
463 | BUG_ON(!th->t_trans_id); | ||
452 | RFALSE(!th->t_super, | 464 | RFALSE(!th->t_super, |
453 | "vs-4060: trying to free block on nonexistent device"); | 465 | "vs-4060: trying to free block on nonexistent device"); |
454 | RFALSE(is_reusable(th->t_super, block, 1) == 0, | 466 | if (!is_reusable(th->t_super, block, 1)) |
455 | "vs-4070: can not free such block"); | 467 | return; |
456 | BUG_ON(!th->t_trans_id); | ||
457 | _reiserfs_free_block(th, inode, block, 1); | 468 | _reiserfs_free_block(th, inode, block, 1); |
458 | } | 469 | } |
459 | 470 | ||
@@ -1207,27 +1218,22 @@ void reiserfs_cache_bitmap_metadata(struct super_block *sb, | |||
1207 | { | 1218 | { |
1208 | unsigned long *cur = (unsigned long *)(bh->b_data + bh->b_size); | 1219 | unsigned long *cur = (unsigned long *)(bh->b_data + bh->b_size); |
1209 | 1220 | ||
1210 | info->first_zero_hint = 1 << (sb->s_blocksize_bits + 3); | 1221 | /* The first bit must ALWAYS be 1 */ |
1222 | BUG_ON(!reiserfs_test_le_bit(0, (unsigned long *)bh->b_data)); | ||
1223 | |||
1224 | info->free_count = 0; | ||
1211 | 1225 | ||
1212 | while (--cur >= (unsigned long *)bh->b_data) { | 1226 | while (--cur >= (unsigned long *)bh->b_data) { |
1213 | int base = ((char *)cur - bh->b_data) << 3; | 1227 | int i; |
1214 | 1228 | ||
1215 | /* 0 and ~0 are special, we can optimize for them */ | 1229 | /* 0 and ~0 are special, we can optimize for them */ |
1216 | if (*cur == 0) { | 1230 | if (*cur == 0) |
1217 | info->first_zero_hint = base; | ||
1218 | info->free_count += BITS_PER_LONG; | 1231 | info->free_count += BITS_PER_LONG; |
1219 | } else if (*cur != ~0L) { /* A mix, investigate */ | 1232 | else if (*cur != ~0L) /* A mix, investigate */ |
1220 | int b; | 1233 | for (i = BITS_PER_LONG - 1; i >= 0; i--) |
1221 | for (b = BITS_PER_LONG - 1; b >= 0; b--) { | 1234 | if (!reiserfs_test_le_bit(i, cur)) |
1222 | if (!reiserfs_test_le_bit(b, cur)) { | ||
1223 | info->first_zero_hint = base + b; | ||
1224 | info->free_count++; | 1235 | info->free_count++; |
1225 | } | ||
1226 | } | ||
1227 | } | ||
1228 | } | 1236 | } |
1229 | /* The first bit must ALWAYS be 1 */ | ||
1230 | BUG_ON(info->first_zero_hint == 0); | ||
1231 | } | 1237 | } |
1232 | 1238 | ||
1233 | struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, | 1239 | struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, |
@@ -1257,7 +1263,7 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, | |||
1257 | BUG_ON(!buffer_uptodate(bh)); | 1263 | BUG_ON(!buffer_uptodate(bh)); |
1258 | BUG_ON(atomic_read(&bh->b_count) == 0); | 1264 | BUG_ON(atomic_read(&bh->b_count) == 0); |
1259 | 1265 | ||
1260 | if (info->first_zero_hint == 0) | 1266 | if (info->free_count == UINT_MAX) |
1261 | reiserfs_cache_bitmap_metadata(sb, bh, info); | 1267 | reiserfs_cache_bitmap_metadata(sb, bh, info); |
1262 | } | 1268 | } |
1263 | 1269 | ||
@@ -1267,12 +1273,13 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, | |||
1267 | int reiserfs_init_bitmap_cache(struct super_block *sb) | 1273 | int reiserfs_init_bitmap_cache(struct super_block *sb) |
1268 | { | 1274 | { |
1269 | struct reiserfs_bitmap_info *bitmap; | 1275 | struct reiserfs_bitmap_info *bitmap; |
1276 | unsigned int bmap_nr = reiserfs_bmap_count(sb); | ||
1270 | 1277 | ||
1271 | bitmap = vmalloc(sizeof (*bitmap) * SB_BMAP_NR(sb)); | 1278 | bitmap = vmalloc(sizeof(*bitmap) * bmap_nr); |
1272 | if (bitmap == NULL) | 1279 | if (bitmap == NULL) |
1273 | return -ENOMEM; | 1280 | return -ENOMEM; |
1274 | 1281 | ||
1275 | memset(bitmap, 0, sizeof (*bitmap) * SB_BMAP_NR(sb)); | 1282 | memset(bitmap, 0xff, sizeof(*bitmap) * bmap_nr); |
1276 | 1283 | ||
1277 | SB_AP_BITMAP(sb) = bitmap; | 1284 | SB_AP_BITMAP(sb) = bitmap; |
1278 | 1285 | ||
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c index 0804289d355d..a991af96f3f0 100644 --- a/fs/reiserfs/inode.c +++ b/fs/reiserfs/inode.c | |||
@@ -199,7 +199,7 @@ static inline void set_block_dev_mapped(struct buffer_head *bh, | |||
199 | // files which were created in the earlier version can not be longer, | 199 | // files which were created in the earlier version can not be longer, |
200 | // than 2 gb | 200 | // than 2 gb |
201 | // | 201 | // |
202 | static int file_capable(struct inode *inode, long block) | 202 | static int file_capable(struct inode *inode, sector_t block) |
203 | { | 203 | { |
204 | if (get_inode_item_key_version(inode) != KEY_FORMAT_3_5 || // it is new file. | 204 | if (get_inode_item_key_version(inode) != KEY_FORMAT_3_5 || // it is new file. |
205 | block < (1 << (31 - inode->i_sb->s_blocksize_bits))) // old file, but 'block' is inside of 2gb | 205 | block < (1 << (31 - inode->i_sb->s_blocksize_bits))) // old file, but 'block' is inside of 2gb |
@@ -242,7 +242,7 @@ static int restart_transaction(struct reiserfs_transaction_handle *th, | |||
242 | // Please improve the english/clarity in the comment above, as it is | 242 | // Please improve the english/clarity in the comment above, as it is |
243 | // hard to understand. | 243 | // hard to understand. |
244 | 244 | ||
245 | static int _get_block_create_0(struct inode *inode, long block, | 245 | static int _get_block_create_0(struct inode *inode, sector_t block, |
246 | struct buffer_head *bh_result, int args) | 246 | struct buffer_head *bh_result, int args) |
247 | { | 247 | { |
248 | INITIALIZE_PATH(path); | 248 | INITIALIZE_PATH(path); |
@@ -250,7 +250,7 @@ static int _get_block_create_0(struct inode *inode, long block, | |||
250 | struct buffer_head *bh; | 250 | struct buffer_head *bh; |
251 | struct item_head *ih, tmp_ih; | 251 | struct item_head *ih, tmp_ih; |
252 | int fs_gen; | 252 | int fs_gen; |
253 | int blocknr; | 253 | b_blocknr_t blocknr; |
254 | char *p = NULL; | 254 | char *p = NULL; |
255 | int chars; | 255 | int chars; |
256 | int ret; | 256 | int ret; |
@@ -569,7 +569,7 @@ static int convert_tail_for_hole(struct inode *inode, | |||
569 | } | 569 | } |
570 | 570 | ||
571 | static inline int _allocate_block(struct reiserfs_transaction_handle *th, | 571 | static inline int _allocate_block(struct reiserfs_transaction_handle *th, |
572 | long block, | 572 | sector_t block, |
573 | struct inode *inode, | 573 | struct inode *inode, |
574 | b_blocknr_t * allocated_block_nr, | 574 | b_blocknr_t * allocated_block_nr, |
575 | struct treepath *path, int flags) | 575 | struct treepath *path, int flags) |
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index 4cad9e75ef56..bb05a3e51b93 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c | |||
@@ -219,11 +219,12 @@ static void allocate_bitmap_nodes(struct super_block *p_s_sb) | |||
219 | } | 219 | } |
220 | } | 220 | } |
221 | 221 | ||
222 | static int set_bit_in_list_bitmap(struct super_block *p_s_sb, int block, | 222 | static int set_bit_in_list_bitmap(struct super_block *p_s_sb, |
223 | b_blocknr_t block, | ||
223 | struct reiserfs_list_bitmap *jb) | 224 | struct reiserfs_list_bitmap *jb) |
224 | { | 225 | { |
225 | int bmap_nr = block / (p_s_sb->s_blocksize << 3); | 226 | unsigned int bmap_nr = block / (p_s_sb->s_blocksize << 3); |
226 | int bit_nr = block % (p_s_sb->s_blocksize << 3); | 227 | unsigned int bit_nr = block % (p_s_sb->s_blocksize << 3); |
227 | 228 | ||
228 | if (!jb->bitmaps[bmap_nr]) { | 229 | if (!jb->bitmaps[bmap_nr]) { |
229 | jb->bitmaps[bmap_nr] = get_bitmap_node(p_s_sb); | 230 | jb->bitmaps[bmap_nr] = get_bitmap_node(p_s_sb); |
@@ -239,7 +240,7 @@ static void cleanup_bitmap_list(struct super_block *p_s_sb, | |||
239 | if (jb->bitmaps == NULL) | 240 | if (jb->bitmaps == NULL) |
240 | return; | 241 | return; |
241 | 242 | ||
242 | for (i = 0; i < SB_BMAP_NR(p_s_sb); i++) { | 243 | for (i = 0; i < reiserfs_bmap_count(p_s_sb); i++) { |
243 | if (jb->bitmaps[i]) { | 244 | if (jb->bitmaps[i]) { |
244 | free_bitmap_node(p_s_sb, jb->bitmaps[i]); | 245 | free_bitmap_node(p_s_sb, jb->bitmaps[i]); |
245 | jb->bitmaps[i] = NULL; | 246 | jb->bitmaps[i] = NULL; |
@@ -289,7 +290,7 @@ static int free_bitmap_nodes(struct super_block *p_s_sb) | |||
289 | */ | 290 | */ |
290 | int reiserfs_allocate_list_bitmaps(struct super_block *p_s_sb, | 291 | int reiserfs_allocate_list_bitmaps(struct super_block *p_s_sb, |
291 | struct reiserfs_list_bitmap *jb_array, | 292 | struct reiserfs_list_bitmap *jb_array, |
292 | int bmap_nr) | 293 | unsigned int bmap_nr) |
293 | { | 294 | { |
294 | int i; | 295 | int i; |
295 | int failed = 0; | 296 | int failed = 0; |
@@ -483,7 +484,7 @@ static inline struct reiserfs_journal_cnode *get_journal_hash_dev(struct | |||
483 | ** | 484 | ** |
484 | */ | 485 | */ |
485 | int reiserfs_in_journal(struct super_block *p_s_sb, | 486 | int reiserfs_in_journal(struct super_block *p_s_sb, |
486 | int bmap_nr, int bit_nr, int search_all, | 487 | unsigned int bmap_nr, int bit_nr, int search_all, |
487 | b_blocknr_t * next_zero_bit) | 488 | b_blocknr_t * next_zero_bit) |
488 | { | 489 | { |
489 | struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb); | 490 | struct reiserfs_journal *journal = SB_JOURNAL(p_s_sb); |
@@ -1013,7 +1014,7 @@ static int flush_commit_list(struct super_block *s, | |||
1013 | struct reiserfs_journal_list *jl, int flushall) | 1014 | struct reiserfs_journal_list *jl, int flushall) |
1014 | { | 1015 | { |
1015 | int i; | 1016 | int i; |
1016 | int bn; | 1017 | b_blocknr_t bn; |
1017 | struct buffer_head *tbh = NULL; | 1018 | struct buffer_head *tbh = NULL; |
1018 | unsigned long trans_id = jl->j_trans_id; | 1019 | unsigned long trans_id = jl->j_trans_id; |
1019 | struct reiserfs_journal *journal = SB_JOURNAL(s); | 1020 | struct reiserfs_journal *journal = SB_JOURNAL(s); |
@@ -2307,8 +2308,9 @@ static int journal_read_transaction(struct super_block *p_s_sb, | |||
2307 | Right now it is only used from journal code. But later we might use it | 2308 | Right now it is only used from journal code. But later we might use it |
2308 | from other places. | 2309 | from other places. |
2309 | Note: Do not use journal_getblk/sb_getblk functions here! */ | 2310 | Note: Do not use journal_getblk/sb_getblk functions here! */ |
2310 | static struct buffer_head *reiserfs_breada(struct block_device *dev, int block, | 2311 | static struct buffer_head *reiserfs_breada(struct block_device *dev, |
2311 | int bufsize, unsigned int max_block) | 2312 | b_blocknr_t block, int bufsize, |
2313 | b_blocknr_t max_block) | ||
2312 | { | 2314 | { |
2313 | struct buffer_head *bhlist[BUFNR]; | 2315 | struct buffer_head *bhlist[BUFNR]; |
2314 | unsigned int blocks = BUFNR; | 2316 | unsigned int blocks = BUFNR; |
@@ -2732,7 +2734,7 @@ int journal_init(struct super_block *p_s_sb, const char *j_dev_name, | |||
2732 | journal->j_persistent_trans = 0; | 2734 | journal->j_persistent_trans = 0; |
2733 | if (reiserfs_allocate_list_bitmaps(p_s_sb, | 2735 | if (reiserfs_allocate_list_bitmaps(p_s_sb, |
2734 | journal->j_list_bitmap, | 2736 | journal->j_list_bitmap, |
2735 | SB_BMAP_NR(p_s_sb))) | 2737 | reiserfs_bmap_count(p_s_sb))) |
2736 | goto free_and_return; | 2738 | goto free_and_return; |
2737 | allocate_bitmap_nodes(p_s_sb); | 2739 | allocate_bitmap_nodes(p_s_sb); |
2738 | 2740 | ||
@@ -2740,7 +2742,7 @@ int journal_init(struct super_block *p_s_sb, const char *j_dev_name, | |||
2740 | SB_JOURNAL_1st_RESERVED_BLOCK(p_s_sb) = (old_format ? | 2742 | SB_JOURNAL_1st_RESERVED_BLOCK(p_s_sb) = (old_format ? |
2741 | REISERFS_OLD_DISK_OFFSET_IN_BYTES | 2743 | REISERFS_OLD_DISK_OFFSET_IN_BYTES |
2742 | / p_s_sb->s_blocksize + | 2744 | / p_s_sb->s_blocksize + |
2743 | SB_BMAP_NR(p_s_sb) + | 2745 | reiserfs_bmap_count(p_s_sb) + |
2744 | 1 : | 2746 | 1 : |
2745 | REISERFS_DISK_OFFSET_IN_BYTES / | 2747 | REISERFS_DISK_OFFSET_IN_BYTES / |
2746 | p_s_sb->s_blocksize + 2); | 2748 | p_s_sb->s_blocksize + 2); |
diff --git a/fs/reiserfs/prints.c b/fs/reiserfs/prints.c index bc808a91eeaa..5e7388b32d02 100644 --- a/fs/reiserfs/prints.c +++ b/fs/reiserfs/prints.c | |||
@@ -356,13 +356,11 @@ extern struct tree_balance *cur_tb; | |||
356 | void reiserfs_panic(struct super_block *sb, const char *fmt, ...) | 356 | void reiserfs_panic(struct super_block *sb, const char *fmt, ...) |
357 | { | 357 | { |
358 | do_reiserfs_warning(fmt); | 358 | do_reiserfs_warning(fmt); |
359 | printk(KERN_EMERG "REISERFS: panic (device %s): %s\n", | ||
360 | reiserfs_bdevname(sb), error_buf); | ||
361 | BUG(); | ||
362 | 359 | ||
363 | /* this is not actually called, but makes reiserfs_panic() "noreturn" */ | 360 | dump_stack(); |
364 | panic("REISERFS: panic (device %s): %s\n", | 361 | |
365 | reiserfs_bdevname(sb), error_buf); | 362 | panic(KERN_EMERG "REISERFS: panic (device %s): %s\n", |
363 | reiserfs_bdevname(sb), error_buf); | ||
366 | } | 364 | } |
367 | 365 | ||
368 | void reiserfs_abort(struct super_block *sb, int errno, const char *fmt, ...) | 366 | void reiserfs_abort(struct super_block *sb, int errno, const char *fmt, ...) |
diff --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c index 976cc7887a0d..f71c3948edef 100644 --- a/fs/reiserfs/resize.c +++ b/fs/reiserfs/resize.c | |||
@@ -61,7 +61,8 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) | |||
61 | } | 61 | } |
62 | 62 | ||
63 | /* count used bits in last bitmap block */ | 63 | /* count used bits in last bitmap block */ |
64 | block_r = SB_BLOCK_COUNT(s) - (SB_BMAP_NR(s) - 1) * s->s_blocksize * 8; | 64 | block_r = SB_BLOCK_COUNT(s) - |
65 | (reiserfs_bmap_count(s) - 1) * s->s_blocksize * 8; | ||
65 | 66 | ||
66 | /* count bitmap blocks in new fs */ | 67 | /* count bitmap blocks in new fs */ |
67 | bmap_nr_new = block_count_new / (s->s_blocksize * 8); | 68 | bmap_nr_new = block_count_new / (s->s_blocksize * 8); |
@@ -73,7 +74,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) | |||
73 | 74 | ||
74 | /* save old values */ | 75 | /* save old values */ |
75 | block_count = SB_BLOCK_COUNT(s); | 76 | block_count = SB_BLOCK_COUNT(s); |
76 | bmap_nr = SB_BMAP_NR(s); | 77 | bmap_nr = reiserfs_bmap_count(s); |
77 | 78 | ||
78 | /* resizing of reiserfs bitmaps (journal and real), if needed */ | 79 | /* resizing of reiserfs bitmaps (journal and real), if needed */ |
79 | if (bmap_nr_new > bmap_nr) { | 80 | if (bmap_nr_new > bmap_nr) { |
@@ -119,7 +120,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) | |||
119 | return -ENOMEM; | 120 | return -ENOMEM; |
120 | } | 121 | } |
121 | memset(bitmap, 0, | 122 | memset(bitmap, 0, |
122 | sizeof(struct reiserfs_bitmap_info) * SB_BMAP_NR(s)); | 123 | sizeof(struct reiserfs_bitmap_info) * bmap_nr_new); |
123 | for (i = 0; i < bmap_nr; i++) | 124 | for (i = 0; i < bmap_nr; i++) |
124 | bitmap[i] = old_bitmap[i]; | 125 | bitmap[i] = old_bitmap[i]; |
125 | 126 | ||
@@ -143,7 +144,6 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) | |||
143 | mark_buffer_dirty(bh); | 144 | mark_buffer_dirty(bh); |
144 | sync_dirty_buffer(bh); | 145 | sync_dirty_buffer(bh); |
145 | // update bitmap_info stuff | 146 | // update bitmap_info stuff |
146 | bitmap[i].first_zero_hint = 1; | ||
147 | bitmap[i].free_count = sb_blocksize(sb) * 8 - 1; | 147 | bitmap[i].free_count = sb_blocksize(sb) * 8 - 1; |
148 | brelse(bh); | 148 | brelse(bh); |
149 | } | 149 | } |
@@ -173,8 +173,6 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) | |||
173 | for (i = block_r; i < s->s_blocksize * 8; i++) | 173 | for (i = block_r; i < s->s_blocksize * 8; i++) |
174 | reiserfs_test_and_clear_le_bit(i, bh->b_data); | 174 | reiserfs_test_and_clear_le_bit(i, bh->b_data); |
175 | info->free_count += s->s_blocksize * 8 - block_r; | 175 | info->free_count += s->s_blocksize * 8 - block_r; |
176 | if (!info->first_zero_hint) | ||
177 | info->first_zero_hint = block_r; | ||
178 | 176 | ||
179 | journal_mark_dirty(&th, s, bh); | 177 | journal_mark_dirty(&th, s, bh); |
180 | brelse(bh); | 178 | brelse(bh); |
@@ -196,9 +194,6 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) | |||
196 | brelse(bh); | 194 | brelse(bh); |
197 | 195 | ||
198 | info->free_count -= s->s_blocksize * 8 - block_r_new; | 196 | info->free_count -= s->s_blocksize * 8 - block_r_new; |
199 | /* Extreme case where last bitmap is the only valid block in itself. */ | ||
200 | if (!info->free_count) | ||
201 | info->first_zero_hint = 0; | ||
202 | /* update super */ | 197 | /* update super */ |
203 | reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); | 198 | reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); |
204 | free_blocks = SB_FREE_BLOCKS(s); | 199 | free_blocks = SB_FREE_BLOCKS(s); |
@@ -206,7 +201,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) | |||
206 | free_blocks + (block_count_new - block_count - | 201 | free_blocks + (block_count_new - block_count - |
207 | (bmap_nr_new - bmap_nr))); | 202 | (bmap_nr_new - bmap_nr))); |
208 | PUT_SB_BLOCK_COUNT(s, block_count_new); | 203 | PUT_SB_BLOCK_COUNT(s, block_count_new); |
209 | PUT_SB_BMAP_NR(s, bmap_nr_new); | 204 | PUT_SB_BMAP_NR(s, bmap_would_wrap(bmap_nr_new) ? : bmap_nr_new); |
210 | s->s_dirt = 1; | 205 | s->s_dirt = 1; |
211 | 206 | ||
212 | journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s)); | 207 | journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s)); |
diff --git a/fs/reiserfs/stree.c b/fs/reiserfs/stree.c index 981027d1187b..ca41567d7890 100644 --- a/fs/reiserfs/stree.c +++ b/fs/reiserfs/stree.c | |||
@@ -559,7 +559,7 @@ static int is_tree_node(struct buffer_head *bh, int level) | |||
559 | /* The function is NOT SCHEDULE-SAFE! */ | 559 | /* The function is NOT SCHEDULE-SAFE! */ |
560 | static void search_by_key_reada(struct super_block *s, | 560 | static void search_by_key_reada(struct super_block *s, |
561 | struct buffer_head **bh, | 561 | struct buffer_head **bh, |
562 | unsigned long *b, int num) | 562 | b_blocknr_t *b, int num) |
563 | { | 563 | { |
564 | int i, j; | 564 | int i, j; |
565 | 565 | ||
@@ -611,7 +611,7 @@ int search_by_key(struct super_block *p_s_sb, const struct cpu_key *p_s_key, /* | |||
611 | DISK_LEAF_NODE_LEVEL */ | 611 | DISK_LEAF_NODE_LEVEL */ |
612 | ) | 612 | ) |
613 | { | 613 | { |
614 | int n_block_number; | 614 | b_blocknr_t n_block_number; |
615 | int expected_level; | 615 | int expected_level; |
616 | struct buffer_head *p_s_bh; | 616 | struct buffer_head *p_s_bh; |
617 | struct path_element *p_s_last_element; | 617 | struct path_element *p_s_last_element; |
@@ -619,7 +619,7 @@ int search_by_key(struct super_block *p_s_sb, const struct cpu_key *p_s_key, /* | |||
619 | int right_neighbor_of_leaf_node; | 619 | int right_neighbor_of_leaf_node; |
620 | int fs_gen; | 620 | int fs_gen; |
621 | struct buffer_head *reada_bh[SEARCH_BY_KEY_READA]; | 621 | struct buffer_head *reada_bh[SEARCH_BY_KEY_READA]; |
622 | unsigned long reada_blocks[SEARCH_BY_KEY_READA]; | 622 | b_blocknr_t reada_blocks[SEARCH_BY_KEY_READA]; |
623 | int reada_count = 0; | 623 | int reada_count = 0; |
624 | 624 | ||
625 | #ifdef CONFIG_REISERFS_CHECK | 625 | #ifdef CONFIG_REISERFS_CHECK |
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index b82897ae090b..57adfe90d5ae 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -1725,6 +1725,21 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) | |||
1725 | set_sb_umount_state(rs, REISERFS_ERROR_FS); | 1725 | set_sb_umount_state(rs, REISERFS_ERROR_FS); |
1726 | set_sb_fs_state(rs, 0); | 1726 | set_sb_fs_state(rs, 0); |
1727 | 1727 | ||
1728 | /* Clear out s_bmap_nr if it would wrap. We can handle this | ||
1729 | * case, but older revisions can't. This will cause the | ||
1730 | * file system to fail mount on those older implementations, | ||
1731 | * avoiding corruption. -jeffm */ | ||
1732 | if (bmap_would_wrap(reiserfs_bmap_count(s)) && | ||
1733 | sb_bmap_nr(rs) != 0) { | ||
1734 | reiserfs_warning(s, "super-2030: This file system " | ||
1735 | "claims to use %u bitmap blocks in " | ||
1736 | "its super block, but requires %u. " | ||
1737 | "Clearing to zero.", sb_bmap_nr(rs), | ||
1738 | reiserfs_bmap_count(s)); | ||
1739 | |||
1740 | set_sb_bmap_nr(rs, 0); | ||
1741 | } | ||
1742 | |||
1728 | if (old_format_only(s)) { | 1743 | if (old_format_only(s)) { |
1729 | /* filesystem of format 3.5 either with standard or non-standard | 1744 | /* filesystem of format 3.5 either with standard or non-standard |
1730 | journal */ | 1745 | journal */ |
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c index fab4b9b2664f..1597f6b649e0 100644 --- a/fs/reiserfs/xattr.c +++ b/fs/reiserfs/xattr.c | |||
@@ -484,7 +484,7 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, | |||
484 | /* Resize it so we're ok to write there */ | 484 | /* Resize it so we're ok to write there */ |
485 | newattrs.ia_size = buffer_size; | 485 | newattrs.ia_size = buffer_size; |
486 | newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; | 486 | newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; |
487 | mutex_lock(&xinode->i_mutex); | 487 | mutex_lock_nested(&xinode->i_mutex, I_MUTEX_XATTR); |
488 | err = notify_change(fp->f_path.dentry, &newattrs); | 488 | err = notify_change(fp->f_path.dentry, &newattrs); |
489 | if (err) | 489 | if (err) |
490 | goto out_filp; | 490 | goto out_filp; |
@@ -1223,7 +1223,8 @@ int reiserfs_xattr_init(struct super_block *s, int mount_flags) | |||
1223 | if (!IS_ERR(dentry)) { | 1223 | if (!IS_ERR(dentry)) { |
1224 | if (!(mount_flags & MS_RDONLY) && !dentry->d_inode) { | 1224 | if (!(mount_flags & MS_RDONLY) && !dentry->d_inode) { |
1225 | struct inode *inode = dentry->d_parent->d_inode; | 1225 | struct inode *inode = dentry->d_parent->d_inode; |
1226 | mutex_lock(&inode->i_mutex); | 1226 | mutex_lock_nested(&inode->i_mutex, |
1227 | I_MUTEX_XATTR); | ||
1227 | err = inode->i_op->mkdir(inode, dentry, 0700); | 1228 | err = inode->i_op->mkdir(inode, dentry, 0700); |
1228 | mutex_unlock(&inode->i_mutex); | 1229 | mutex_unlock(&inode->i_mutex); |
1229 | if (err) { | 1230 | if (err) { |
diff --git a/fs/select.c b/fs/select.c index 7dede89658f5..47f47925aea2 100644 --- a/fs/select.c +++ b/fs/select.c | |||
@@ -177,11 +177,6 @@ get_max: | |||
177 | return max; | 177 | return max; |
178 | } | 178 | } |
179 | 179 | ||
180 | #define BIT(i) (1UL << ((i)&(__NFDBITS-1))) | ||
181 | #define MEM(i,m) ((m)+(unsigned)(i)/__NFDBITS) | ||
182 | #define ISSET(i,m) (((i)&*(m)) != 0) | ||
183 | #define SET(i,m) (*(m) |= (i)) | ||
184 | |||
185 | #define POLLIN_SET (POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP | POLLERR) | 180 | #define POLLIN_SET (POLLRDNORM | POLLRDBAND | POLLIN | POLLHUP | POLLERR) |
186 | #define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR) | 181 | #define POLLOUT_SET (POLLWRBAND | POLLWRNORM | POLLOUT | POLLERR) |
187 | #define POLLEX_SET (POLLPRI) | 182 | #define POLLEX_SET (POLLPRI) |
diff --git a/fs/super.c b/fs/super.c index 1bfcca2104be..d28fde7e1cfb 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -40,10 +40,6 @@ | |||
40 | #include <asm/uaccess.h> | 40 | #include <asm/uaccess.h> |
41 | 41 | ||
42 | 42 | ||
43 | void get_filesystem(struct file_system_type *fs); | ||
44 | void put_filesystem(struct file_system_type *fs); | ||
45 | struct file_system_type *get_fs_type(const char *name); | ||
46 | |||
47 | LIST_HEAD(super_blocks); | 43 | LIST_HEAD(super_blocks); |
48 | DEFINE_SPINLOCK(sb_lock); | 44 | DEFINE_SPINLOCK(sb_lock); |
49 | 45 | ||
@@ -336,21 +332,21 @@ struct super_block *sget(struct file_system_type *type, | |||
336 | void *data) | 332 | void *data) |
337 | { | 333 | { |
338 | struct super_block *s = NULL; | 334 | struct super_block *s = NULL; |
339 | struct list_head *p; | 335 | struct super_block *old; |
340 | int err; | 336 | int err; |
341 | 337 | ||
342 | retry: | 338 | retry: |
343 | spin_lock(&sb_lock); | 339 | spin_lock(&sb_lock); |
344 | if (test) list_for_each(p, &type->fs_supers) { | 340 | if (test) { |
345 | struct super_block *old; | 341 | list_for_each_entry(old, &type->fs_supers, s_instances) { |
346 | old = list_entry(p, struct super_block, s_instances); | 342 | if (!test(old, data)) |
347 | if (!test(old, data)) | 343 | continue; |
348 | continue; | 344 | if (!grab_super(old)) |
349 | if (!grab_super(old)) | 345 | goto retry; |
350 | goto retry; | 346 | if (s) |
351 | if (s) | 347 | destroy_super(s); |
352 | destroy_super(s); | 348 | return old; |
353 | return old; | 349 | } |
354 | } | 350 | } |
355 | if (!s) { | 351 | if (!s) { |
356 | spin_unlock(&sb_lock); | 352 | spin_unlock(&sb_lock); |
@@ -948,9 +944,9 @@ do_kern_mount(const char *fstype, int flags, const char *name, void *data) | |||
948 | return mnt; | 944 | return mnt; |
949 | } | 945 | } |
950 | 946 | ||
951 | struct vfsmount *kern_mount(struct file_system_type *type) | 947 | struct vfsmount *kern_mount_data(struct file_system_type *type, void *data) |
952 | { | 948 | { |
953 | return vfs_kern_mount(type, 0, type->name, NULL); | 949 | return vfs_kern_mount(type, MS_KERNMOUNT, type->name, data); |
954 | } | 950 | } |
955 | 951 | ||
956 | EXPORT_SYMBOL(kern_mount); | 952 | EXPORT_SYMBOL_GPL(kern_mount_data); |
diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c index 726449d4fd22..3586c7a28d2c 100644 --- a/fs/xfs/linux-2.6/xfs_export.c +++ b/fs/xfs/linux-2.6/xfs_export.c | |||
@@ -54,8 +54,8 @@ xfs_fs_decode_fh( | |||
54 | struct dentry *de), | 54 | struct dentry *de), |
55 | void *context) | 55 | void *context) |
56 | { | 56 | { |
57 | xfs_fid2_t ifid; | 57 | xfs_fid_t ifid; |
58 | xfs_fid2_t pfid; | 58 | xfs_fid_t pfid; |
59 | void *parent = NULL; | 59 | void *parent = NULL; |
60 | int is64 = 0; | 60 | int is64 = 0; |
61 | __u32 *p = fh; | 61 | __u32 *p = fh; |
@@ -144,7 +144,7 @@ xfs_fs_get_dentry( | |||
144 | struct dentry *result; | 144 | struct dentry *result; |
145 | int error; | 145 | int error; |
146 | 146 | ||
147 | error = xfs_vget(XFS_M(sb), &vp, (fid_t *)data); | 147 | error = xfs_vget(XFS_M(sb), &vp, data); |
148 | if (error || vp == NULL) | 148 | if (error || vp == NULL) |
149 | return ERR_PTR(-ESTALE) ; | 149 | return ERR_PTR(-ESTALE) ; |
150 | 150 | ||
diff --git a/fs/xfs/linux-2.6/xfs_export.h b/fs/xfs/linux-2.6/xfs_export.h index e794ca4efc76..2f36071a86f7 100644 --- a/fs/xfs/linux-2.6/xfs_export.h +++ b/fs/xfs/linux-2.6/xfs_export.h | |||
@@ -71,13 +71,13 @@ xfs_fileid_length(int hasparent, int is64) | |||
71 | 71 | ||
72 | /* | 72 | /* |
73 | * Decode encoded inode information (either for the inode itself | 73 | * Decode encoded inode information (either for the inode itself |
74 | * or the parent) into an xfs_fid2_t structure. Advances and | 74 | * or the parent) into an xfs_fid_t structure. Advances and |
75 | * returns the new data pointer | 75 | * returns the new data pointer |
76 | */ | 76 | */ |
77 | static inline __u32 * | 77 | static inline __u32 * |
78 | xfs_fileid_decode_fid2(__u32 *p, xfs_fid2_t *fid, int is64) | 78 | xfs_fileid_decode_fid2(__u32 *p, xfs_fid_t *fid, int is64) |
79 | { | 79 | { |
80 | fid->fid_len = sizeof(xfs_fid2_t) - sizeof(fid->fid_len); | 80 | fid->fid_len = sizeof(xfs_fid_t) - sizeof(fid->fid_len); |
81 | fid->fid_pad = 0; | 81 | fid->fid_pad = 0; |
82 | fid->fid_ino = *p++; | 82 | fid->fid_ino = *p++; |
83 | #if XFS_BIG_INUMS | 83 | #if XFS_BIG_INUMS |
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c index ffec630e7db7..2b34bad48b07 100644 --- a/fs/xfs/linux-2.6/xfs_ioctl.c +++ b/fs/xfs/linux-2.6/xfs_ioctl.c | |||
@@ -152,11 +152,11 @@ xfs_find_handle( | |||
152 | lock_mode = xfs_ilock_map_shared(ip); | 152 | lock_mode = xfs_ilock_map_shared(ip); |
153 | 153 | ||
154 | /* fill in fid section of handle from inode */ | 154 | /* fill in fid section of handle from inode */ |
155 | handle.ha_fid.xfs_fid_len = sizeof(xfs_fid_t) - | 155 | handle.ha_fid.fid_len = sizeof(xfs_fid_t) - |
156 | sizeof(handle.ha_fid.xfs_fid_len); | 156 | sizeof(handle.ha_fid.fid_len); |
157 | handle.ha_fid.xfs_fid_pad = 0; | 157 | handle.ha_fid.fid_pad = 0; |
158 | handle.ha_fid.xfs_fid_gen = ip->i_d.di_gen; | 158 | handle.ha_fid.fid_gen = ip->i_d.di_gen; |
159 | handle.ha_fid.xfs_fid_ino = ip->i_ino; | 159 | handle.ha_fid.fid_ino = ip->i_ino; |
160 | 160 | ||
161 | xfs_iunlock_map_shared(ip, lock_mode); | 161 | xfs_iunlock_map_shared(ip, lock_mode); |
162 | 162 | ||
@@ -222,10 +222,10 @@ xfs_vget_fsop_handlereq( | |||
222 | if (hlen < sizeof(*handlep)) | 222 | if (hlen < sizeof(*handlep)) |
223 | memset(((char *)handlep) + hlen, 0, sizeof(*handlep) - hlen); | 223 | memset(((char *)handlep) + hlen, 0, sizeof(*handlep) - hlen); |
224 | if (hlen > sizeof(handlep->ha_fsid)) { | 224 | if (hlen > sizeof(handlep->ha_fsid)) { |
225 | if (handlep->ha_fid.xfs_fid_len != | 225 | if (handlep->ha_fid.fid_len != |
226 | (hlen - sizeof(handlep->ha_fsid) | 226 | (hlen - sizeof(handlep->ha_fsid) - |
227 | - sizeof(handlep->ha_fid.xfs_fid_len)) | 227 | sizeof(handlep->ha_fid.fid_len)) || |
228 | || handlep->ha_fid.xfs_fid_pad) | 228 | handlep->ha_fid.fid_pad) |
229 | return XFS_ERROR(EINVAL); | 229 | return XFS_ERROR(EINVAL); |
230 | } | 230 | } |
231 | 231 | ||
@@ -233,9 +233,9 @@ xfs_vget_fsop_handlereq( | |||
233 | * Crack the handle, obtain the inode # & generation # | 233 | * Crack the handle, obtain the inode # & generation # |
234 | */ | 234 | */ |
235 | xfid = (struct xfs_fid *)&handlep->ha_fid; | 235 | xfid = (struct xfs_fid *)&handlep->ha_fid; |
236 | if (xfid->xfs_fid_len == sizeof(*xfid) - sizeof(xfid->xfs_fid_len)) { | 236 | if (xfid->fid_len == sizeof(*xfid) - sizeof(xfid->fid_len)) { |
237 | ino = xfid->xfs_fid_ino; | 237 | ino = xfid->fid_ino; |
238 | igen = xfid->xfs_fid_gen; | 238 | igen = xfid->fid_gen; |
239 | } else { | 239 | } else { |
240 | return XFS_ERROR(EINVAL); | 240 | return XFS_ERROR(EINVAL); |
241 | } | 241 | } |
diff --git a/fs/xfs/xfs_dmops.c b/fs/xfs/xfs_dmops.c index 6cd5704258a2..a1e55fb9d5dd 100644 --- a/fs/xfs/xfs_dmops.c +++ b/fs/xfs/xfs_dmops.c | |||
@@ -41,29 +41,16 @@ int | |||
41 | xfs_dmops_get(struct xfs_mount *mp, struct xfs_mount_args *args) | 41 | xfs_dmops_get(struct xfs_mount *mp, struct xfs_mount_args *args) |
42 | { | 42 | { |
43 | if (args->flags & XFSMNT_DMAPI) { | 43 | if (args->flags & XFSMNT_DMAPI) { |
44 | struct xfs_dmops *ops; | 44 | cmn_err(CE_WARN, |
45 | 45 | "XFS: dmapi support not available in this kernel."); | |
46 | ops = symbol_get(xfs_dmcore_xfs); | 46 | return EINVAL; |
47 | if (!ops) { | ||
48 | request_module("xfs_dmapi"); | ||
49 | ops = symbol_get(xfs_dmcore_xfs); | ||
50 | } | ||
51 | |||
52 | if (!ops) { | ||
53 | cmn_err(CE_WARN, "XFS: no dmapi support available."); | ||
54 | return EINVAL; | ||
55 | } | ||
56 | mp->m_dm_ops = ops; | ||
57 | } else { | ||
58 | mp->m_dm_ops = &xfs_dmcore_stub; | ||
59 | } | 47 | } |
60 | 48 | ||
49 | mp->m_dm_ops = &xfs_dmcore_stub; | ||
61 | return 0; | 50 | return 0; |
62 | } | 51 | } |
63 | 52 | ||
64 | void | 53 | void |
65 | xfs_dmops_put(struct xfs_mount *mp) | 54 | xfs_dmops_put(struct xfs_mount *mp) |
66 | { | 55 | { |
67 | if (mp->m_dm_ops != &xfs_dmcore_stub) | ||
68 | symbol_put(xfs_dmcore_xfs); | ||
69 | } | 56 | } |
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h index ec3c9c27e0de..aab966276517 100644 --- a/fs/xfs/xfs_fs.h +++ b/fs/xfs/xfs_fs.h | |||
@@ -389,30 +389,13 @@ typedef struct xfs_fsop_attrmulti_handlereq { | |||
389 | */ | 389 | */ |
390 | typedef struct { __u32 val[2]; } xfs_fsid_t; /* file system id type */ | 390 | typedef struct { __u32 val[2]; } xfs_fsid_t; /* file system id type */ |
391 | 391 | ||
392 | |||
393 | #ifndef HAVE_FID | ||
394 | #define MAXFIDSZ 46 | ||
395 | |||
396 | typedef struct fid { | ||
397 | __u16 fid_len; /* length of data in bytes */ | ||
398 | unsigned char fid_data[MAXFIDSZ]; /* data (fid_len worth) */ | ||
399 | } fid_t; | ||
400 | #endif | ||
401 | |||
402 | typedef struct xfs_fid { | 392 | typedef struct xfs_fid { |
403 | __u16 xfs_fid_len; /* length of remainder */ | 393 | __u16 fid_len; /* length of remainder */ |
404 | __u16 xfs_fid_pad; | 394 | __u16 fid_pad; |
405 | __u32 xfs_fid_gen; /* generation number */ | 395 | __u32 fid_gen; /* generation number */ |
406 | __u64 xfs_fid_ino; /* 64 bits inode number */ | 396 | __u64 fid_ino; /* 64 bits inode number */ |
407 | } xfs_fid_t; | 397 | } xfs_fid_t; |
408 | 398 | ||
409 | typedef struct xfs_fid2 { | ||
410 | __u16 fid_len; /* length of remainder */ | ||
411 | __u16 fid_pad; /* padding, must be zero */ | ||
412 | __u32 fid_gen; /* generation number */ | ||
413 | __u64 fid_ino; /* inode number */ | ||
414 | } xfs_fid2_t; | ||
415 | |||
416 | typedef struct xfs_handle { | 399 | typedef struct xfs_handle { |
417 | union { | 400 | union { |
418 | __s64 align; /* force alignment of ha_fid */ | 401 | __s64 align; /* force alignment of ha_fid */ |
@@ -422,9 +405,9 @@ typedef struct xfs_handle { | |||
422 | } xfs_handle_t; | 405 | } xfs_handle_t; |
423 | #define ha_fsid ha_u._ha_fsid | 406 | #define ha_fsid ha_u._ha_fsid |
424 | 407 | ||
425 | #define XFS_HSIZE(handle) (((char *) &(handle).ha_fid.xfs_fid_pad \ | 408 | #define XFS_HSIZE(handle) (((char *) &(handle).ha_fid.fid_pad \ |
426 | - (char *) &(handle)) \ | 409 | - (char *) &(handle)) \ |
427 | + (handle).ha_fid.xfs_fid_len) | 410 | + (handle).ha_fid.fid_len) |
428 | 411 | ||
429 | /* | 412 | /* |
430 | * Flags for going down operation | 413 | * Flags for going down operation |
diff --git a/fs/xfs/xfs_qmops.c b/fs/xfs/xfs_qmops.c index c266a0184b42..2ec1d8a27352 100644 --- a/fs/xfs/xfs_qmops.c +++ b/fs/xfs/xfs_qmops.c | |||
@@ -135,19 +135,13 @@ int | |||
135 | xfs_qmops_get(struct xfs_mount *mp, struct xfs_mount_args *args) | 135 | xfs_qmops_get(struct xfs_mount *mp, struct xfs_mount_args *args) |
136 | { | 136 | { |
137 | if (args->flags & (XFSMNT_UQUOTA | XFSMNT_PQUOTA | XFSMNT_GQUOTA)) { | 137 | if (args->flags & (XFSMNT_UQUOTA | XFSMNT_PQUOTA | XFSMNT_GQUOTA)) { |
138 | struct xfs_qmops *ops; | 138 | #ifdef CONFIG_XFS_QUOTA |
139 | 139 | mp->m_qm_ops = &xfs_qmcore_xfs; | |
140 | ops = symbol_get(xfs_qmcore_xfs); | 140 | #else |
141 | if (!ops) { | 141 | cmn_err(CE_WARN, |
142 | request_module("xfs_quota"); | 142 | "XFS: qouta support not available in this kernel."); |
143 | ops = symbol_get(xfs_qmcore_xfs); | 143 | return EINVAL; |
144 | } | 144 | #endif |
145 | |||
146 | if (!ops) { | ||
147 | cmn_err(CE_WARN, "XFS: no quota support available."); | ||
148 | return EINVAL; | ||
149 | } | ||
150 | mp->m_qm_ops = ops; | ||
151 | } else { | 145 | } else { |
152 | mp->m_qm_ops = &xfs_qmcore_stub; | 146 | mp->m_qm_ops = &xfs_qmcore_stub; |
153 | } | 147 | } |
@@ -158,6 +152,4 @@ xfs_qmops_get(struct xfs_mount *mp, struct xfs_mount_args *args) | |||
158 | void | 152 | void |
159 | xfs_qmops_put(struct xfs_mount *mp) | 153 | xfs_qmops_put(struct xfs_mount *mp) |
160 | { | 154 | { |
161 | if (mp->m_qm_ops != &xfs_qmcore_stub) | ||
162 | symbol_put(xfs_qmcore_xfs); | ||
163 | } | 155 | } |
diff --git a/fs/xfs/xfs_vfsops.c b/fs/xfs/xfs_vfsops.c index a5a8454f2a63..a1544597bcd3 100644 --- a/fs/xfs/xfs_vfsops.c +++ b/fs/xfs/xfs_vfsops.c | |||
@@ -1635,9 +1635,8 @@ int | |||
1635 | xfs_vget( | 1635 | xfs_vget( |
1636 | xfs_mount_t *mp, | 1636 | xfs_mount_t *mp, |
1637 | bhv_vnode_t **vpp, | 1637 | bhv_vnode_t **vpp, |
1638 | fid_t *fidp) | 1638 | xfs_fid_t *xfid) |
1639 | { | 1639 | { |
1640 | xfs_fid_t *xfid = (struct xfs_fid *)fidp; | ||
1641 | xfs_inode_t *ip; | 1640 | xfs_inode_t *ip; |
1642 | int error; | 1641 | int error; |
1643 | xfs_ino_t ino; | 1642 | xfs_ino_t ino; |
@@ -1647,11 +1646,11 @@ xfs_vget( | |||
1647 | * Invalid. Since handles can be created in user space and passed in | 1646 | * Invalid. Since handles can be created in user space and passed in |
1648 | * via gethandle(), this is not cause for a panic. | 1647 | * via gethandle(), this is not cause for a panic. |
1649 | */ | 1648 | */ |
1650 | if (xfid->xfs_fid_len != sizeof(*xfid) - sizeof(xfid->xfs_fid_len)) | 1649 | if (xfid->fid_len != sizeof(*xfid) - sizeof(xfid->fid_len)) |
1651 | return XFS_ERROR(EINVAL); | 1650 | return XFS_ERROR(EINVAL); |
1652 | 1651 | ||
1653 | ino = xfid->xfs_fid_ino; | 1652 | ino = xfid->fid_ino; |
1654 | igen = xfid->xfs_fid_gen; | 1653 | igen = xfid->fid_gen; |
1655 | 1654 | ||
1656 | /* | 1655 | /* |
1657 | * NFS can sometimes send requests for ino 0. Fail them gracefully. | 1656 | * NFS can sometimes send requests for ino 0. Fail them gracefully. |
diff --git a/fs/xfs/xfs_vfsops.h b/fs/xfs/xfs_vfsops.h index bc99e3eb7dbb..a592fe02a339 100644 --- a/fs/xfs/xfs_vfsops.h +++ b/fs/xfs/xfs_vfsops.h | |||
@@ -2,7 +2,7 @@ | |||
2 | #define _XFS_VFSOPS_H 1 | 2 | #define _XFS_VFSOPS_H 1 |
3 | 3 | ||
4 | struct cred; | 4 | struct cred; |
5 | struct fid; | 5 | struct xfs_fid; |
6 | struct inode; | 6 | struct inode; |
7 | struct kstatfs; | 7 | struct kstatfs; |
8 | struct xfs_mount; | 8 | struct xfs_mount; |
@@ -17,7 +17,7 @@ int xfs_root(struct xfs_mount *mp, bhv_vnode_t **vpp); | |||
17 | int xfs_statvfs(struct xfs_mount *mp, struct kstatfs *statp, | 17 | int xfs_statvfs(struct xfs_mount *mp, struct kstatfs *statp, |
18 | bhv_vnode_t *vp); | 18 | bhv_vnode_t *vp); |
19 | int xfs_sync(struct xfs_mount *mp, int flags); | 19 | int xfs_sync(struct xfs_mount *mp, int flags); |
20 | int xfs_vget(struct xfs_mount *mp, bhv_vnode_t **vpp, struct fid *fidp); | 20 | int xfs_vget(struct xfs_mount *mp, bhv_vnode_t **vpp, struct xfs_fid *xfid); |
21 | int xfs_parseargs(struct xfs_mount *mp, char *options, | 21 | int xfs_parseargs(struct xfs_mount *mp, char *options, |
22 | struct xfs_mount_args *args, int update); | 22 | struct xfs_mount_args *args, int update); |
23 | int xfs_showargs(struct xfs_mount *mp, struct seq_file *m); | 23 | int xfs_showargs(struct xfs_mount *mp, struct seq_file *m); |
diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 5e3c57ca9981..efd5aff9eaf6 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c | |||
@@ -3466,23 +3466,14 @@ std_return: | |||
3466 | } | 3466 | } |
3467 | 3467 | ||
3468 | 3468 | ||
3469 | /* | ||
3470 | * xfs_fid2 | ||
3471 | * | ||
3472 | * A fid routine that takes a pointer to a previously allocated | ||
3473 | * fid structure (like xfs_fast_fid) but uses a 64 bit inode number. | ||
3474 | */ | ||
3475 | int | 3469 | int |
3476 | xfs_fid2( | 3470 | xfs_fid2( |
3477 | xfs_inode_t *ip, | 3471 | xfs_inode_t *ip, |
3478 | fid_t *fidp) | 3472 | xfs_fid_t *xfid) |
3479 | { | 3473 | { |
3480 | xfs_fid2_t *xfid = (xfs_fid2_t *)fidp; | ||
3481 | |||
3482 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); | 3474 | vn_trace_entry(ip, __FUNCTION__, (inst_t *)__return_address); |
3483 | ASSERT(sizeof(fid_t) >= sizeof(xfs_fid2_t)); | ||
3484 | 3475 | ||
3485 | xfid->fid_len = sizeof(xfs_fid2_t) - sizeof(xfid->fid_len); | 3476 | xfid->fid_len = sizeof(xfs_fid_t) - sizeof(xfid->fid_len); |
3486 | xfid->fid_pad = 0; | 3477 | xfid->fid_pad = 0; |
3487 | /* | 3478 | /* |
3488 | * use memcpy because the inode is a long long and there's no | 3479 | * use memcpy because the inode is a long long and there's no |
diff --git a/fs/xfs/xfs_vnodeops.h b/fs/xfs/xfs_vnodeops.h index f36e74f2f0c2..b7e461c40cfb 100644 --- a/fs/xfs/xfs_vnodeops.h +++ b/fs/xfs/xfs_vnodeops.h | |||
@@ -39,7 +39,7 @@ int xfs_readdir(struct xfs_inode *dp, void *dirent, size_t bufsize, | |||
39 | int xfs_symlink(struct xfs_inode *dp, bhv_vname_t *dentry, | 39 | int xfs_symlink(struct xfs_inode *dp, bhv_vname_t *dentry, |
40 | char *target_path, mode_t mode, bhv_vnode_t **vpp, | 40 | char *target_path, mode_t mode, bhv_vnode_t **vpp, |
41 | struct cred *credp); | 41 | struct cred *credp); |
42 | int xfs_fid2(struct xfs_inode *ip, fid_t *fidp); | 42 | int xfs_fid2(struct xfs_inode *ip, struct xfs_fid *xfid); |
43 | int xfs_rwlock(struct xfs_inode *ip, bhv_vrwlock_t locktype); | 43 | int xfs_rwlock(struct xfs_inode *ip, bhv_vrwlock_t locktype); |
44 | void xfs_rwunlock(struct xfs_inode *ip, bhv_vrwlock_t locktype); | 44 | void xfs_rwunlock(struct xfs_inode *ip, bhv_vrwlock_t locktype); |
45 | int xfs_inode_flush(struct xfs_inode *ip, int flags); | 45 | int xfs_inode_flush(struct xfs_inode *ip, int flags); |