cregit-Linux how code gets into the kernel

Release 4.10 fs/ncpfs/ncplib_kernel.c

Directory: fs/ncpfs
/*
 *  ncplib_kernel.c
 *
 *  Copyright (C) 1995, 1996 by Volker Lendecke
 *  Modified for big endian by J.F. Chadima and David S. Miller
 *  Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache
 *  Modified 1999 Wolfram Pienkoss for NLS
 *  Modified 2000 Ben Harris, University of Cambridge for NFS NS meta-info
 *
 */


#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include "ncp_fs.h"


static inline void assert_server_locked(struct ncp_server *server) { if (server->lock == 0) { ncp_dbg(1, "server not locked!\n"); } }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git2586.21%266.67%
joe perchesjoe perches413.79%133.33%
Total29100.00%3100.00%


static void ncp_add_byte(struct ncp_server *server, __u8 x) { assert_server_locked(server); *(__u8 *) (&(server->packet[server->current_size])) = x; server->current_size += 1; return; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git47100.00%2100.00%
Total47100.00%2100.00%


static void ncp_add_word(struct ncp_server *server, __le16 x) { assert_server_locked(server); put_unaligned(x, (__le16 *) (&(server->packet[server->current_size]))); server->current_size += 2; return; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git4795.92%266.67%
al viroal viro24.08%133.33%
Total49100.00%3100.00%


static void ncp_add_be16(struct ncp_server *server, __u16 x) { assert_server_locked(server); put_unaligned(cpu_to_be16(x), (__be16 *) (&(server->packet[server->current_size]))); server->current_size += 2; }

Contributors

PersonTokensPropCommitsCommitProp
al viroal viro51100.00%1100.00%
Total51100.00%1100.00%


static void ncp_add_dword(struct ncp_server *server, __le32 x) { assert_server_locked(server); put_unaligned(x, (__le32 *) (&(server->packet[server->current_size]))); server->current_size += 4; return; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git4795.92%266.67%
al viroal viro24.08%133.33%
Total49100.00%3100.00%


static void ncp_add_be32(struct ncp_server *server, __u32 x) { assert_server_locked(server); put_unaligned(cpu_to_be32(x), (__be32 *)(&(server->packet[server->current_size]))); server->current_size += 4; }

Contributors

PersonTokensPropCommitsCommitProp
al viroal viro51100.00%1100.00%
Total51100.00%1100.00%


static inline void ncp_add_dword_lh(struct ncp_server *server, __u32 x) { ncp_add_dword(server, cpu_to_le32(x)); }

Contributors

PersonTokensPropCommitsCommitProp
petr vandrovec*petr vandrovec*25100.00%1100.00%
Total25100.00%1100.00%


static void ncp_add_mem(struct ncp_server *server, const void *source, int size) { assert_server_locked(server); memcpy(&(server->packet[server->current_size]), source, size); server->current_size += size; return; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git50100.00%1100.00%
Total50100.00%1100.00%


static void ncp_add_pstring(struct ncp_server *server, const char *s) { int len = strlen(s); assert_server_locked(server); if (len > 255) { ncp_dbg(1, "string too long: %s\n", s); len = 255; } ncp_add_byte(server, len); ncp_add_mem(server, s, len); return; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git6394.03%150.00%
joe perchesjoe perches45.97%150.00%
Total67100.00%2100.00%


static inline void ncp_init_request(struct ncp_server *server) { ncp_lock_server(server); server->current_size = sizeof(struct ncp_request_header); server->has_subfunction = 0; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git33100.00%2100.00%
Total33100.00%2100.00%


static inline void ncp_init_request_s(struct ncp_server *server, int subfunction) { ncp_lock_server(server); server->current_size = sizeof(struct ncp_request_header) + 2; ncp_add_byte(server, subfunction); server->has_subfunction = 1; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git45100.00%2100.00%
Total45100.00%2100.00%


static inline char * ncp_reply_data(struct ncp_server *server, int offset) { return &(server->packet[sizeof(struct ncp_reply_header) + offset]); }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git33100.00%2100.00%
Total33100.00%2100.00%


static inline u8 BVAL(const void *data) { return *(const u8 *)data; }

Contributors

PersonTokensPropCommitsCommitProp
petr vandrovec*petr vandrovec*1676.19%133.33%
harvey harrisonharvey harrison314.29%133.33%
petr vandrovecpetr vandrovec29.52%133.33%
Total21100.00%3100.00%


static u8 ncp_reply_byte(struct ncp_server *server, int offset) { return *(const u8 *)ncp_reply_data(server, offset); }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git2382.14%133.33%
harvey harrisonharvey harrison414.29%133.33%
petr vandrovecpetr vandrovec13.57%133.33%
Total28100.00%3100.00%


static inline u16 WVAL_LH(const void *data) { return get_unaligned_le16(data); }

Contributors

PersonTokensPropCommitsCommitProp
petr vandrovec*petr vandrovec*1583.33%133.33%
harvey harrisonharvey harrison211.11%133.33%
petr vandrovecpetr vandrovec15.56%133.33%
Total18100.00%3100.00%


static u16 ncp_reply_le16(struct ncp_server *server, int offset) { return get_unaligned_le16(ncp_reply_data(server, offset)); }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git2288.00%250.00%
harvey harrisonharvey harrison28.00%125.00%
al viroal viro14.00%125.00%
Total25100.00%4100.00%


static u16 ncp_reply_be16(struct ncp_server *server, int offset) { return get_unaligned_be16(ncp_reply_data(server, offset)); }

Contributors

PersonTokensPropCommitsCommitProp
al viroal viro2392.00%150.00%
harvey harrisonharvey harrison28.00%150.00%
Total25100.00%2100.00%


static inline u32 DVAL_LH(const void *data) { return get_unaligned_le32(data); }

Contributors

PersonTokensPropCommitsCommitProp
petr vandrovec*petr vandrovec*1583.33%133.33%
harvey harrisonharvey harrison211.11%133.33%
petr vandrovecpetr vandrovec15.56%133.33%
Total18100.00%3100.00%


static __le32 ncp_reply_dword(struct ncp_server *server, int offset) { return get_unaligned((__le32 *)ncp_reply_data(server, offset)); }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git2793.10%266.67%
al viroal viro26.90%133.33%
Total29100.00%3100.00%


static inline __u32 ncp_reply_dword_lh(struct ncp_server* server, int offset) { return le32_to_cpu(ncp_reply_dword(server, offset)); }

Contributors

PersonTokensPropCommitsCommitProp
petr vandrovec*petr vandrovec*26100.00%1100.00%
Total26100.00%1100.00%


int ncp_negotiate_buffersize(struct ncp_server *server, int size, int *target) { int result; ncp_init_request(server); ncp_add_be16(server, size); if ((result = ncp_request(server, 33)) != 0) { ncp_unlock_server(server); return result; } *target = min_t(unsigned int, ncp_reply_be16(server, 0), size); ncp_unlock_server(server); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git7392.41%240.00%
al viroal viro33.80%120.00%
linus torvaldslinus torvalds33.80%240.00%
Total79100.00%5100.00%

/* options: * bit 0 ipx checksum * bit 1 packet signing */
int ncp_negotiate_size_and_options(struct ncp_server *server, int size, int options, int *ret_size, int *ret_options) { int result; /* there is minimum */ if (size < NCP_BLOCK_SIZE) size = NCP_BLOCK_SIZE; ncp_init_request(server); ncp_add_be16(server, size); ncp_add_byte(server, options); if ((result = ncp_request(server, 0x61)) != 0) { ncp_unlock_server(server); return result; } /* NCP over UDP returns 0 (!!!) */ result = ncp_reply_be16(server, 0); if (result >= NCP_BLOCK_SIZE) size = min(result, size); *ret_size = size; *ret_options = ncp_reply_byte(server, 4); ncp_unlock_server(server); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git12898.46%375.00%
al viroal viro21.54%125.00%
Total130100.00%4100.00%


int ncp_get_volume_info_with_number(struct ncp_server* server, int n, struct ncp_volume_info* target) { int result; int len; ncp_init_request_s(server, 44); ncp_add_byte(server, n); if ((result = ncp_request(server, 22)) != 0) { goto out; } target->total_blocks = ncp_reply_dword_lh(server, 0); target->free_blocks = ncp_reply_dword_lh(server, 4); target->purgeable_blocks = ncp_reply_dword_lh(server, 8); target->not_yet_purgeable_blocks = ncp_reply_dword_lh(server, 12); target->total_dir_entries = ncp_reply_dword_lh(server, 16); target->available_dir_entries = ncp_reply_dword_lh(server, 20); target->sectors_per_block = ncp_reply_byte(server, 28); memset(&(target->volume_name), 0, sizeof(target->volume_name)); result = -EIO; len = ncp_reply_byte(server, 29); if (len > NCP_VOLNAME_LEN) { ncp_dbg(1, "volume name too long: %d\n", len); goto out; } memcpy(&(target->volume_name), ncp_reply_data(server, 30), len); result = 0; out: ncp_unlock_server(server); return result; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git21095.02%250.00%
petr vandrovec*petr vandrovec*73.17%125.00%
joe perchesjoe perches41.81%125.00%
Total221100.00%4100.00%


int ncp_get_directory_info(struct ncp_server* server, __u8 n, struct ncp_volume_info* target) { int result; int len; ncp_init_request_s(server, 45); ncp_add_byte(server, n); if ((result = ncp_request(server, 22)) != 0) { goto out; } target->total_blocks = ncp_reply_dword_lh(server, 0); target->free_blocks = ncp_reply_dword_lh(server, 4); target->purgeable_blocks = 0; target->not_yet_purgeable_blocks = 0; target->total_dir_entries = ncp_reply_dword_lh(server, 8); target->available_dir_entries = ncp_reply_dword_lh(server, 12); target->sectors_per_block = ncp_reply_byte(server, 20); memset(&(target->volume_name), 0, sizeof(target->volume_name)); result = -EIO; len = ncp_reply_byte(server, 21); if (len > NCP_VOLNAME_LEN) { ncp_dbg(1, "volume name too long: %d\n", len); goto out; } memcpy(&(target->volume_name), ncp_reply_data(server, 22), len); result = 0; out: ncp_unlock_server(server); return result; }

Contributors

PersonTokensPropCommitsCommitProp
petr vandrovec*petr vandrovec*20798.10%150.00%
joe perchesjoe perches41.90%150.00%
Total211100.00%2100.00%


int ncp_close_file(struct ncp_server *server, const char *file_id) { int result; ncp_init_request(server); ncp_add_byte(server, 0); ncp_add_mem(server, file_id, 6); result = ncp_request(server, 66); ncp_unlock_server(server); return result; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git56100.00%3100.00%
Total56100.00%3100.00%


int ncp_make_closed(struct inode *inode) { int err; err = 0; mutex_lock(&NCP_FINFO(inode)->open_mutex); if (atomic_read(&NCP_FINFO(inode)->opened) == 1) { atomic_set(&NCP_FINFO(inode)->opened, 0); err = ncp_close_file(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle); if (!err) ncp_vdbg("volnum=%d, dirent=%u, error=%d\n", NCP_FINFO(inode)->volNumber, NCP_FINFO(inode)->dirEntNum, err); } mutex_unlock(&NCP_FINFO(inode)->open_mutex); return err; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git10994.78%250.00%
ingo molnaringo molnar43.48%125.00%
joe perchesjoe perches21.74%125.00%
Total115100.00%4100.00%


static void ncp_add_handle_path(struct ncp_server *server, __u8 vol_num, __le32 dir_base, int have_dir_base, const char *path) { ncp_add_byte(server, vol_num); ncp_add_dword(server, dir_base); if (have_dir_base != 0) { ncp_add_byte(server, 1); /* dir_base */ } else { ncp_add_byte(server, 0xff); /* no handle */ } if (path != NULL) { ncp_add_byte(server, 1); /* 1 component */ ncp_add_pstring(server, path); } else { ncp_add_byte(server, 0); } }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git9898.99%266.67%
al viroal viro11.01%133.33%
Total99100.00%3100.00%


int ncp_dirhandle_alloc(struct ncp_server* server, __u8 volnum, __le32 dirent, __u8* dirhandle) { int result; ncp_init_request(server); ncp_add_byte(server, 12); /* subfunction */ ncp_add_byte(server, NW_NS_DOS); ncp_add_byte(server, 0); ncp_add_word(server, 0); ncp_add_handle_path(server, volnum, dirent, 1, NULL); if ((result = ncp_request(server, 87)) == 0) { *dirhandle = ncp_reply_byte(server, 0); } ncp_unlock_server(server); return result; }

Contributors

PersonTokensPropCommitsCommitProp
petr vandrovec*petr vandrovec*10499.05%150.00%
al viroal viro10.95%150.00%
Total105100.00%2100.00%


int ncp_dirhandle_free(struct ncp_server* server, __u8 dirhandle) { int result; ncp_init_request_s(server, 20); ncp_add_byte(server, dirhandle); result = ncp_request(server, 22); ncp_unlock_server(server); return result; }

Contributors

PersonTokensPropCommitsCommitProp
petr vandrovec*petr vandrovec*47100.00%1100.00%
Total47100.00%1100.00%


void ncp_extract_file_info(const void *structure, struct nw_info_struct *target) { const __u8 *name_len; const int info_struct_size = offsetof(struct nw_info_struct, nameLen); memcpy(target, structure, info_struct_size); name_len = structure + info_struct_size; target->nameLen = *name_len; memcpy(target->entryName, name_len + 1, *name_len); target->entryName[*name_len] = '\0'; target->volNumber = le32_to_cpu(target->volNumber); return; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git7482.22%240.00%
petr vandrovec*petr vandrovec*1415.56%240.00%
petr vandrovecpetr vandrovec22.22%120.00%
Total90100.00%5100.00%

#ifdef CONFIG_NCPFS_NFS_NS
static inline void ncp_extract_nfs_info(const unsigned char *structure, struct nw_nfs_info *target) { target->mode = DVAL_LH(structure); target->rdev = DVAL_LH(structure + 8); }

Contributors

PersonTokensPropCommitsCommitProp
petr vandrovec*petr vandrovec*3797.37%150.00%
petr vandrovecpetr vandrovec12.63%150.00%
Total38100.00%2100.00%

#endif
int ncp_obtain_nfs_info(struct ncp_server *server, struct nw_info_struct *target) { int result = 0; #ifdef CONFIG_NCPFS_NFS_NS __u32 volnum = target->volNumber; if (ncp_is_nfs_extras(server, volnum)) { ncp_init_request(server); ncp_add_byte(server, 19); /* subfunction */ ncp_add_byte(server, server->name_space[volnum]); ncp_add_byte(server, NW_NS_NFS); ncp_add_byte(server, 0); ncp_add_byte(server, volnum); ncp_add_dword(server, target->dirEntNum); /* We must retrieve both nlinks and rdev, otherwise some server versions report zeroes instead of valid data */ ncp_add_dword_lh(server, NSIBM_NFS_MODE | NSIBM_NFS_NLINKS | NSIBM_NFS_RDEV); if ((result = ncp_request(server, 87)) == 0) { ncp_extract_nfs_info(ncp_reply_data(server, 0), &target->nfs); ncp_dbg(1, "(%s) mode=0%o, rdev=0x%x\n", target->entryName, target->nfs.mode, target->nfs.rdev); } else { target->nfs.mode = 0; target->nfs.rdev = 0; } ncp_unlock_server(server); } else #endif { target->nfs.mode = 0; target->nfs.rdev = 0; } return result; }

Contributors

PersonTokensPropCommitsCommitProp
petr vandrovec*petr vandrovec*20798.10%150.00%
joe perchesjoe perches41.90%150.00%
Total211100.00%2100.00%

/* * Returns information for a (one-component) name relative to * the specified directory. */
int ncp_obtain_info(struct ncp_server *server, struct inode *dir, const char *path, struct nw_info_struct *target) { __u8 volnum = NCP_FINFO(dir)->volNumber; __le32 dirent = NCP_FINFO(dir)->dirEntNum; int result; if (target == NULL) { pr_err("%s: invalid call\n", __func__); return -EINVAL; } ncp_init_request(server); ncp_add_byte(server, 6); /* subfunction */ ncp_add_byte(server, server->name_space[volnum]); ncp_add_byte(server, server->name_space[volnum]); /* N.B. twice ?? */ ncp_add_word(server, cpu_to_le16(0x8006)); /* get all */ ncp_add_dword(server, RIM_ALL); ncp_add_handle_path(server, volnum, dirent, 1, path); if ((result = ncp_request(server, 87)) != 0) goto out; ncp_extract_file_info(ncp_reply_data(server, 0), target); ncp_unlock_server(server); result = ncp_obtain_nfs_info(server, target); return result; out: ncp_unlock_server(server); return result; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git16887.05%654.55%
petr vandrovec*petr vandrovec*178.81%19.09%
joe perchesjoe perches42.07%19.09%
al viroal viro31.55%218.18%
petr vandrovecpetr vandrovec10.52%19.09%
Total193100.00%11100.00%

#ifdef CONFIG_NCPFS_NFS_NS
static int ncp_obtain_DOS_dir_base(struct ncp_server *server, __u8 ns, __u8 volnum, __le32 dirent, const char *path, /* At most 1 component */ __le32 *DOS_dir_base) { int result; ncp_init_request(server); ncp_add_byte(server, 6); /* subfunction */ ncp_add_byte(server, ns); ncp_add_byte(server, ns); ncp_add_word(server, cpu_to_le16(0x8006)); /* get all */ ncp_add_dword(server, RIM_DIRECTORY); ncp_add_handle_path(server, volnum, dirent, 1, path); if ((result = ncp_request(server, 87)) == 0) { if (DOS_dir_base) *DOS_dir_base=ncp_reply_dword(server, 0x34); } ncp_unlock_server(server); return result; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git12092.31%240.00%
petr vandrovecpetr vandrovec64.62%120.00%
al viroal viro43.08%240.00%
Total130100.00%5100.00%

#endif /* CONFIG_NCPFS_NFS_NS */
static inline int ncp_get_known_namespace(struct ncp_server *server, __u8 volume) { #if defined(CONFIG_NCPFS_OS2_NS) || defined(CONFIG_NCPFS_NFS_NS) int result; __u8 *namespace; __u16 no_namespaces; ncp_init_request(server); ncp_add_byte(server, 24); /* Subfunction: Get Name Spaces Loaded */ ncp_add_word(server, 0); ncp_add_byte(server, volume); if ((result = ncp_request(server, 87)) != 0) { ncp_unlock_server(server); return NW_NS_DOS; /* not result ?? */ } result = NW_NS_DOS; no_namespaces = ncp_reply_le16(server, 0); namespace = ncp_reply_data(server, 2); while (no_namespaces > 0) { ncp_dbg(1, "found %d on %d\n", *namespace, volume); #ifdef CONFIG_NCPFS_NFS_NS if ((*namespace == NW_NS_NFS) && !(server->m.flags&NCP_MOUNT_NO_NFS)) { result = NW_NS_NFS; break; } #endif /* CONFIG_NCPFS_NFS_NS */ #ifdef CONFIG_NCPFS_OS2_NS if ((*namespace == NW_NS_OS2) && !(server->m.flags&NCP_MOUNT_NO_OS2)) { result = NW_NS_OS2; } #endif /* CONFIG_NCPFS_OS2_NS */ namespace += 1; no_namespaces -= 1; } ncp_unlock_server(server); return result; #else /* neither OS2 nor NFS - only DOS */ return NW_NS_DOS; #endif /* defined(CONFIG_NCPFS_OS2_NS) || defined(CONFIG_NCPFS_NFS_NS) */ }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git21697.74%360.00%
joe perchesjoe perches41.81%120.00%
al viroal viro10.45%120.00%
Total221100.00%5100.00%


int ncp_update_known_namespace(struct ncp_server *server, __u8 volume, int *ret_ns) { int ns = ncp_get_known_namespace(server, volume); if (ret_ns) *ret_ns = ns; ncp_dbg(1, "namespace[%d] = %d\n", volume, server->name_space[volume]); if (server->name_space[volume] == ns) return 0; server->name_space[volume] = ns; return 1; }

Contributors

PersonTokensPropCommitsCommitProp
petr vandrovecpetr vandrovec7494.87%150.00%
joe perchesjoe perches45.13%150.00%
Total78100.00%2100.00%


static int ncp_ObtainSpecificDirBase(struct ncp_server *server, __u8 nsSrc, __u8 nsDst, __u8 vol_num, __le32 dir_base, const char *path, /* At most 1 component */ __le32 *dirEntNum, __le32 *DosDirNum) { int result; ncp_init_request(server); ncp_add_byte(server, 6); /* subfunction */ ncp_add_byte(server, nsSrc); ncp_add_byte(server, nsDst); ncp_add_word(server, cpu_to_le16(0x8006)); /* get all */ ncp_add_dword(server, RIM_ALL); ncp_add_handle_path(server, vol_num, dir_base, 1, path); if ((result = ncp_request(server, 87)) != 0) { ncp_unlock_server(server); return result; } if (dirEntNum) *dirEntNum = ncp_reply_dword(server, 0x30); if (DosDirNum) *DosDirNum = ncp_reply_dword(server, 0x34); ncp_unlock_server(server); return 0; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git15396.23%457.14%
al viroal viro53.14%228.57%
petr vandrovecpetr vandrovec10.63%114.29%
Total159100.00%7100.00%


int ncp_mount_subdir(struct ncp_server *server, __u8 volNumber, __u8 srcNS, __le32 dirEntNum, __u32* volume, __le32* newDirEnt, __le32* newDosEnt) { int dstNS; int result; ncp_update_known_namespace(server, volNumber, &dstNS); if ((result = ncp_ObtainSpecificDirBase(server, srcNS, dstNS, volNumber, dirEntNum, NULL, newDirEnt, newDosEnt)) != 0) { return result; } *volume = volNumber; server->m.mounted_vol[1] = 0; server->m.mounted_vol[0] = 'X'; return 0; }

Contributors

PersonTokensPropCommitsCommitProp
pre-gitpre-git9082.57%350.00%
petr vandrovec*petr vandrovec*1211.01%116.67%
petr vandrovecpetr vandrovec43.67%116.67%
al viroal viro32.75%116.67%
Total109100.00%6100.00%


int ncp_get_volume_root(struct ncp_server *server, const char *volname, __u32*