vserver 1.9.5.x5
[linux-2.6.git] / fs / smbfs / proc.c
index 418c0c3..220babe 100644 (file)
@@ -74,7 +74,7 @@ smb_proc_setattr_core(struct smb_sb_info *server, struct dentry *dentry,
 static int
 smb_proc_setattr_ext(struct smb_sb_info *server,
                     struct inode *inode, struct smb_fattr *fattr);
-int
+static int
 smb_proc_query_cifsunix(struct smb_sb_info *server);
 static void
 install_ops(struct smb_ops *dst, struct smb_ops *src);
@@ -1427,9 +1427,9 @@ smb_proc_readX_data(struct smb_request *req)
         * So we must first calculate the amount of padding used by the server.
         */
        data_off -= hdrlen;
-       if (data_off > SMB_READX_MAX_PAD) {
-               PARANOIA("offset is larger than max pad!\n");
-               PARANOIA("%d > %d\n", data_off, SMB_READX_MAX_PAD);
+       if (data_off > SMB_READX_MAX_PAD || data_off < 0) {
+               PARANOIA("offset is larger than SMB_READX_MAX_PAD or negative!\n");
+               PARANOIA("%d > %d || %d < 0\n", data_off, SMB_READX_MAX_PAD, data_off);
                req->rq_rlen = req->rq_bufsize + 1;
                return;
        }
@@ -1852,12 +1852,13 @@ smb_finish_dirent(struct smb_sb_info *server, struct smb_fattr *fattr)
 }
 
 void
-smb_init_root_dirent(struct smb_sb_info *server, struct smb_fattr *fattr)
+smb_init_root_dirent(struct smb_sb_info *server, struct smb_fattr *fattr,
+                    struct super_block *sb)
 {
        smb_init_dirent(server, fattr);
        fattr->attr = aDIR;
        fattr->f_ino = 2; /* traditional root inode number */
-       fattr->f_mtime = CURRENT_TIME;
+       fattr->f_mtime = current_fs_time(sb);
        smb_finish_dirent(server, fattr);
 }
 
@@ -2074,7 +2075,7 @@ out:
        return result;
 }
 
-void smb_decode_unix_basic(struct smb_fattr *fattr, char *p)
+static void smb_decode_unix_basic(struct smb_fattr *fattr, struct smb_sb_info *server, char *p)
 {
        u64 size, disk_bytes;
 
@@ -2111,8 +2112,17 @@ void smb_decode_unix_basic(struct smb_fattr *fattr, char *p)
        fattr->f_ctime = smb_ntutc2unixutc(LVAL(p, 16));
        fattr->f_atime = smb_ntutc2unixutc(LVAL(p, 24));
        fattr->f_mtime = smb_ntutc2unixutc(LVAL(p, 32));
-       fattr->f_uid = LVAL(p, 40); 
-       fattr->f_gid = LVAL(p, 48); 
+
+       if (server->mnt->flags & SMB_MOUNT_UID)
+               fattr->f_uid = server->mnt->uid;
+       else
+               fattr->f_uid = LVAL(p, 40);
+
+       if (server->mnt->flags & SMB_MOUNT_GID)
+               fattr->f_gid = server->mnt->gid;
+       else
+               fattr->f_gid = LVAL(p, 48);
+
        fattr->f_mode |= smb_filetype_to_mode(WVAL(p, 56));
 
        if (S_ISBLK(fattr->f_mode) || S_ISCHR(fattr->f_mode)) {
@@ -2121,10 +2131,20 @@ void smb_decode_unix_basic(struct smb_fattr *fattr, char *p)
 
                fattr->f_rdev = MKDEV(major & 0xffffffff, minor & 0xffffffff);
                if (MAJOR(fattr->f_rdev) != (major & 0xffffffff) ||
-                   MINOR(fattr->f_rdev) != (minor & 0xffffffff))
+               MINOR(fattr->f_rdev) != (minor & 0xffffffff))
                        fattr->f_rdev = 0;
        }
+
        fattr->f_mode |= LVAL(p, 84);
+
+       if ( (server->mnt->flags & SMB_MOUNT_DMODE) &&
+            (S_ISDIR(fattr->f_mode)) )
+               fattr->f_mode = (server->mnt->dir_mode & S_IRWXUGO) | S_IFDIR;
+       else if ( (server->mnt->flags & SMB_MOUNT_FMODE) &&
+                 !(S_ISDIR(fattr->f_mode)) )
+               fattr->f_mode = (server->mnt->file_mode & S_IRWXUGO) |
+                               (fattr->f_mode & S_IFMT);
+
 }
 
 /*
@@ -2210,7 +2230,7 @@ smb_decode_long_dirent(struct smb_sb_info *server, char *p, int level,
                /* FIXME: should we check the length?? */
 
                p += 8;
-               smb_decode_unix_basic(fattr, p);
+               smb_decode_unix_basic(fattr, server, p);
                VERBOSE("info SMB_FIND_FILE_UNIX at %p, len=%d, name=%.*s\n",
                        p, len, len, qname->name);
                break;
@@ -2769,7 +2789,7 @@ smb_proc_getattr_unix(struct smb_sb_info *server, struct dentry *dir,
        if (result < 0)
                goto out_free;
 
-       smb_decode_unix_basic(attr, req->rq_data);
+       smb_decode_unix_basic(attr, server, req->rq_data);
 
 out_free:
        smb_rput(req);
@@ -3372,7 +3392,7 @@ out:
        return result;
 }
 
-int
+static int
 smb_proc_query_cifsunix(struct smb_sb_info *server)
 {
        int result;