smbd/vfs.c

ソースコードを見る。

データ構造

struct  vfs_init_function_entry

関数

static struct vfs_init_function_entryvfs_find_backend_entry (const char *name)
NTSTATUS smb_register_vfs (int version, const char *name, vfs_op_tuple *vfs_op_tuples)
static void vfs_init_default (connection_struct *conn)
static void vfs_set_operation (struct vfs_ops *vfs, vfs_op_type which, struct vfs_handle_struct *handle, void *op)
BOOL vfs_init_custom (connection_struct *conn, const char *vfs_object)
void * vfs_add_fsp_extension_notype (vfs_handle_struct *handle, files_struct *fsp, size_t ext_size)
void vfs_remove_fsp_extension (vfs_handle_struct *handle, files_struct *fsp)
void * vfs_fetch_fsp_extension (vfs_handle_struct *handle, files_struct *fsp)
BOOL smbd_vfs_init (connection_struct *conn)
BOOL vfs_directory_exist (connection_struct *conn, const char *dname, SMB_STRUCT_STAT *st)
BOOL vfs_object_exist (connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf)
BOOL vfs_file_exist (connection_struct *conn, const char *fname, SMB_STRUCT_STAT *sbuf)
ssize_t vfs_read_data (files_struct *fsp, char *buf, size_t byte_count)
ssize_t vfs_pread_data (files_struct *fsp, char *buf, size_t byte_count, SMB_OFF_T offset)
ssize_t vfs_write_data (files_struct *fsp, const char *buffer, size_t N)
ssize_t vfs_pwrite_data (files_struct *fsp, const char *buffer, size_t N, SMB_OFF_T offset)
int vfs_allocate_file_space (files_struct *fsp, SMB_BIG_UINT len)
int vfs_set_filelen (files_struct *fsp, SMB_OFF_T len)
int vfs_fill_sparse (files_struct *fsp, SMB_OFF_T len)
static ssize_t read_fn (int fd, void *buf, size_t len)
static ssize_t write_fn (int fd, const void *buf, size_t len)
SMB_OFF_T vfs_transfer_file (files_struct *in, files_struct *out, SMB_OFF_T n)
char * vfs_readdirname (connection_struct *conn, void *p)
int vfs_ChDir (connection_struct *conn, const char *path)
static void array_promote (char *array, int elsize, int element)
char * vfs_GetWd (connection_struct *conn, char *path)
NTSTATUS reduce_name (connection_struct *conn, const pstring fname)

変数

 static_decl_vfs
static struct vfs_init_function_entrybackends = NULL
static char * sparse_buf
static files_structin_fsp
static files_structout_fsp
struct {
   SMB_DEV_T   dev
   SMB_INO_T   inode
   char *   dos_path
   BOOL   valid
ino_list [MAX_GETWDCACHE]
BOOL use_getwd_cache


関数

static struct vfs_init_function_entry* vfs_find_backend_entry ( const char *  name  )  [static]

vfs.c45 行で定義されています。

参照先 backendsvfs_init_function_entry::namevfs_init_function_entry::next.

参照元 smb_register_vfs()vfs_init_custom().

00046 {
00047         struct vfs_init_function_entry *entry = backends;
00048  
00049         while(entry) {
00050                 if (strcmp(entry->name, name)==0) return entry;
00051                 entry = entry->next;
00052         }
00053 
00054         return NULL;
00055 }

NTSTATUS smb_register_vfs ( int  version,
const char *  name,
vfs_op_tuple vfs_op_tuples 
)

vfs.c57 行で定義されています。

参照先 backendsvfs_init_function_entry::namesmb_xstrdup()vfs_find_backend_entry()vfs_init_function_entry::vfs_op_tuples.

参照元 vfs_afsacl_init()vfs_aixacl2_init()vfs_aixacl_init()vfs_audit_init()vfs_cacheprime_init()vfs_cap_init()vfs_catia_init()vfs_commit_init()vfs_default_init()vfs_default_quota_init()vfs_expand_msdfs_init()vfs_extd_audit_init()vfs_fake_perms_init()vfs_full_audit_init()vfs_gpfs_init()vfs_hpuxacl_init()vfs_irixacl_init()vfs_netatalk_init()vfs_notify_fam_init()vfs_posixacl_init()vfs_prealloc_init()vfs_readahead_init()vfs_readonly_init()vfs_recycle_init()vfs_shadow_copy_init()vfs_solarisacl_init()vfs_tru64acl_init().

00058 {
00059         struct vfs_init_function_entry *entry = backends;
00060 
00061         if ((version != SMB_VFS_INTERFACE_VERSION)) {
00062                 DEBUG(0, ("Failed to register vfs module.\n"
00063                           "The module was compiled against SMB_VFS_INTERFACE_VERSION %d,\n"
00064                           "current SMB_VFS_INTERFACE_VERSION is %d.\n"
00065                           "Please recompile against the current Samba Version!\n",  
00066                           version, SMB_VFS_INTERFACE_VERSION));
00067                 return NT_STATUS_OBJECT_TYPE_MISMATCH;
00068         }
00069 
00070         if (!name || !name[0] || !vfs_op_tuples) {
00071                 DEBUG(0,("smb_register_vfs() called with NULL pointer or empty name!\n"));
00072                 return NT_STATUS_INVALID_PARAMETER;
00073         }
00074 
00075         if (vfs_find_backend_entry(name)) {
00076                 DEBUG(0,("VFS module %s already loaded!\n", name));
00077                 return NT_STATUS_OBJECT_NAME_COLLISION;
00078         }
00079 
00080         entry = SMB_XMALLOC_P(struct vfs_init_function_entry);
00081         entry->name = smb_xstrdup(name);
00082         entry->vfs_op_tuples = vfs_op_tuples;
00083 
00084         DLIST_ADD(backends, entry);
00085         DEBUG(5, ("Successfully added vfs backend '%s'\n", name));
00086         return NT_STATUS_OK;
00087 }

static void vfs_init_default ( connection_struct conn  )  [static]

vfs.c93 行で定義されています。

参照先 vfs_init_custom().

参照元 smbd_vfs_init().

00094 {
00095         DEBUG(3, ("Initialising default vfs hooks\n"));
00096         vfs_init_custom(conn, DEFAULT_VFS_MODULE_NAME);
00097 }

static void vfs_set_operation ( struct vfs_ops vfs,
vfs_op_type  which,
struct vfs_handle_struct handle,
void *  op 
) [inline, static]

vfs.c103 行で定義されています。

参照先 handlevfs_ops::handlesvfs_ops::ops.

参照元 vfs_init_custom().

00105 {
00106         ((struct vfs_handle_struct **)&vfs->handles)[which] = handle;
00107         ((void **)(void *)&vfs->ops)[which] = op;
00108 }

BOOL vfs_init_custom ( connection_struct conn,
const char *  vfs_object 
)

vfs.c110 行で定義されています。

参照先 backendshandleconnection_struct::mem_ctxvfs_op_tuple::opsmb_probe_module()SMB_VFS_LAYER_OPAQUEsmb_xstrdup()strchr_m()talloc_strdup()trim_char()vfs_op_tuple::typetypeconnection_struct::vfsvfs_find_backend_entry()connection_struct::vfs_handlesvfs_init_function_entry::vfs_op_tuplesconnection_struct::vfs_opaquevfs_set_operation().

参照元 cmd_load_module()smbd_vfs_init()vfs_init_default().

00111 {
00112         vfs_op_tuple *ops;
00113         char *module_name = NULL;
00114         char *module_param = NULL, *p;
00115         int i;
00116         vfs_handle_struct *handle;
00117         struct vfs_init_function_entry *entry;
00118         
00119         if (!conn||!vfs_object||!vfs_object[0]) {
00120                 DEBUG(0,("vfs_init_custon() called with NULL pointer or emtpy vfs_object!\n"));
00121                 return False;
00122         }
00123 
00124         if(!backends) {
00125                 static_init_vfs;
00126         }
00127 
00128         DEBUG(3, ("Initialising custom vfs hooks from [%s]\n", vfs_object));
00129 
00130         module_name = smb_xstrdup(vfs_object);
00131 
00132         p = strchr_m(module_name, ':');
00133 
00134         if (p) {
00135                 *p = 0;
00136                 module_param = p+1;
00137                 trim_char(module_param, ' ', ' ');
00138         }
00139 
00140         trim_char(module_name, ' ', ' ');
00141 
00142         /* First, try to load the module with the new module system */
00143         if((entry = vfs_find_backend_entry(module_name)) || 
00144            (NT_STATUS_IS_OK(smb_probe_module("vfs", module_name)) && 
00145                 (entry = vfs_find_backend_entry(module_name)))) {
00146 
00147                 DEBUGADD(5,("Successfully loaded vfs module [%s] with the new modules system\n", vfs_object));
00148                 
00149                 if ((ops = entry->vfs_op_tuples) == NULL) {
00150                         DEBUG(0, ("entry->vfs_op_tuples==NULL for [%s] failed\n", vfs_object));
00151                         SAFE_FREE(module_name);
00152                         return False;
00153                 }
00154         } else {
00155                 DEBUG(0,("Can't find a vfs module [%s]\n",vfs_object));
00156                 SAFE_FREE(module_name);
00157                 return False;
00158         }
00159 
00160         handle = TALLOC_ZERO_P(conn->mem_ctx,vfs_handle_struct);
00161         if (!handle) {
00162                 DEBUG(0,("TALLOC_ZERO() failed!\n"));
00163                 SAFE_FREE(module_name);
00164                 return False;
00165         }
00166         memcpy(&handle->vfs_next, &conn->vfs, sizeof(struct vfs_ops));
00167         handle->conn = conn;
00168         if (module_param) {
00169                 handle->param = talloc_strdup(conn->mem_ctx, module_param);
00170         }
00171         DLIST_ADD(conn->vfs_handles, handle);
00172 
00173         for(i=0; ops[i].op != NULL; i++) {
00174                 DEBUG(5, ("Checking operation #%d (type %d, layer %d)\n", i, ops[i].type, ops[i].layer));
00175                 if(ops[i].layer == SMB_VFS_LAYER_OPAQUE) {
00176                         /* If this operation was already made opaque by different module, it
00177                          * will be overridden here.
00178                          */
00179                         DEBUGADD(5, ("Making operation type %d opaque [module %s]\n", ops[i].type, vfs_object));
00180                         vfs_set_operation(&conn->vfs_opaque, ops[i].type, handle, ops[i].op);
00181                 }
00182                 /* Change current VFS disposition*/
00183                 DEBUGADD(5, ("Accepting operation type %d from module %s\n", ops[i].type, vfs_object));
00184                 vfs_set_operation(&conn->vfs, ops[i].type, handle, ops[i].op);
00185         }
00186 
00187         SAFE_FREE(module_name);
00188         return True;
00189 }

void* vfs_add_fsp_extension_notype ( vfs_handle_struct handle,
files_struct fsp,
size_t  ext_size 
)

vfs.c199 行で定義されています。

参照先 handlevfs_fsp_data::nextvfs_fsp_data::ownerfiles_struct::vfs_extensionvfs_fetch_fsp_extension().

00200 {
00201         struct vfs_fsp_data *ext;
00202         void * ext_data;
00203 
00204         /* Prevent VFS modules adding multiple extensions. */
00205         if ((ext_data = vfs_fetch_fsp_extension(handle, fsp))) {
00206                 return ext_data;
00207         }
00208 
00209         ext = (struct vfs_fsp_data *)TALLOC_ZERO(
00210                 handle->conn->mem_ctx, sizeof(struct vfs_fsp_data) + ext_size);
00211         if (ext == NULL) {
00212                 return NULL;
00213         }
00214 
00215         ext->owner = handle;
00216         ext->next = fsp->vfs_extension;
00217         fsp->vfs_extension = ext;
00218         return EXT_DATA_AREA(ext);
00219 }

void vfs_remove_fsp_extension ( vfs_handle_struct handle,
files_struct fsp 
)

vfs.c221 行で定義されています。

参照先 handlevfs_fsp_data::nextvfs_fsp_data::ownerfiles_struct::vfs_extension.

00222 {
00223         struct vfs_fsp_data *curr;
00224         struct vfs_fsp_data *prev;
00225 
00226         for (curr = fsp->vfs_extension, prev = NULL;
00227              curr;
00228              prev = curr, curr = curr->next) {
00229                 if (curr->owner == handle) {
00230                     if (prev) {
00231                             prev->next = curr->next;
00232                     } else {
00233                             fsp->vfs_extension = curr->next;
00234                     }
00235                     TALLOC_FREE(curr);
00236                     return;
00237                 }
00238         }
00239 }

void* vfs_fetch_fsp_extension ( vfs_handle_struct handle,
files_struct fsp 
)

vfs.c241 行で定義されています。

参照先 handlevfs_fsp_data::nextvfs_fsp_data::ownerfiles_struct::vfs_extension.

参照元 vfs_add_fsp_extension_notype().

00242 {
00243         struct vfs_fsp_data *head;
00244 
00245         for (head = fsp->vfs_extension; head; head = head->next) {
00246                 if (head->owner == handle) {
00247                         return EXT_DATA_AREA(head);
00248                 }
00249         }
00250 
00251         return NULL;
00252 }

BOOL smbd_vfs_init ( connection_struct conn  ) 

vfs.c260 行で定義されています。

参照先 vfs_init_custom()vfs_init_default().

参照元 create_conn_struct()get_nt_acl_no_snum()main().

00261 {
00262         const char **vfs_objects;
00263         unsigned int i = 0;
00264         int j = 0;
00265         
00266         /* Normal share - initialise with disk access functions */
00267         vfs_init_default(conn);
00268         vfs_objects = lp_vfs_objects(SNUM(conn));
00269 
00270         /* Override VFS functions if 'vfs object' was not specified*/
00271         if (!vfs_objects || !vfs_objects[0])
00272                 return True;
00273         
00274         for (i=0; vfs_objects[i] ;) {
00275                 i++;
00276         }
00277 
00278         for (j=i-1; j >= 0; j--) {
00279                 if (!vfs_init_custom(conn, vfs_objects[j])) {
00280                         DEBUG(0, ("smbd_vfs_init: vfs_init_custom failed for %s\n", vfs_objects[j]));
00281                         return False;
00282                 }
00283         }
00284         return True;
00285 }

BOOL vfs_directory_exist ( connection_struct conn,
const char *  dname,
SMB_STRUCT_STAT *  st 
)

vfs.c291 行で定義されています。

参照先 errno.

参照元 reply_setdir().

00292 {
00293         SMB_STRUCT_STAT st2;
00294         BOOL ret;
00295 
00296         if (!st)
00297                 st = &st2;
00298 
00299         if (SMB_VFS_STAT(conn,dname,st) != 0)
00300                 return(False);
00301 
00302         ret = S_ISDIR(st->st_mode);
00303         if(!ret)
00304                 errno = ENOTDIR;
00305 
00306         return ret;
00307 }

BOOL vfs_object_exist ( connection_struct conn,
const char *  fname,
SMB_STRUCT_STAT *  sbuf 
)

vfs.c313 行で定義されています。

参照元 rename_internals()rename_internals_fsp().

00314 {
00315         SMB_STRUCT_STAT st;
00316 
00317         if (!sbuf)
00318                 sbuf = &st;
00319 
00320         ZERO_STRUCTP(sbuf);
00321 
00322         if (SMB_VFS_STAT(conn,fname,sbuf) == -1)
00323                 return(False);
00324         return True;
00325 }

BOOL vfs_file_exist ( connection_struct conn,
const char *  fname,
SMB_STRUCT_STAT *  sbuf 
)

vfs.c331 行で定義されています。

参照元 copy_file()get_correct_cversion()rename_internals().

00332 {
00333         SMB_STRUCT_STAT st;
00334 
00335         if (!sbuf)
00336                 sbuf = &st;
00337 
00338         ZERO_STRUCTP(sbuf);
00339 
00340         if (SMB_VFS_STAT(conn,fname,sbuf) == -1)
00341                 return False;
00342         return(S_ISREG(sbuf->st_mode));
00343 }

ssize_t vfs_read_data ( files_struct fsp,
char *  buf,
size_t  byte_count 
)

vfs.c349 行で定義されています。

参照先 errnofd_handle::fdfiles_struct::fhtotal.

参照元 get_file_version().

00350 {
00351         size_t total=0;
00352 
00353         while (total < byte_count)
00354         {
00355                 ssize_t ret = SMB_VFS_READ(fsp, fsp->fh->fd, buf + total,
00356                                         byte_count - total);
00357 
00358                 if (ret == 0) return total;
00359                 if (ret == -1) {
00360                         if (errno == EINTR)
00361                                 continue;
00362                         else
00363                                 return -1;
00364                 }
00365                 total += ret;
00366         }
00367         return (ssize_t)total;
00368 }

ssize_t vfs_pread_data ( files_struct fsp,
char *  buf,
size_t  byte_count,
SMB_OFF_T  offset 
)

vfs.c370 行で定義されています。

参照先 errnofd_handle::fdfiles_struct::fhtotal.

00372 {
00373         size_t total=0;
00374 
00375         while (total < byte_count)
00376         {
00377                 ssize_t ret = SMB_VFS_PREAD(fsp, fsp->fh->fd, buf + total,
00378                                         byte_count - total, offset + total);
00379 
00380                 if (ret == 0) return total;
00381                 if (ret == -1) {
00382                         if (errno == EINTR)
00383                                 continue;
00384                         else
00385                                 return -1;
00386                 }
00387                 total += ret;
00388         }
00389         return (ssize_t)total;
00390 }

ssize_t vfs_write_data ( files_struct fsp,
const char *  buffer,
size_t  N 
)

vfs.c396 行で定義されています。

参照先 fd_handle::fdfiles_struct::fhtotal.

参照元 real_write_file().

00397 {
00398         size_t total=0;
00399         ssize_t ret;
00400 
00401         while (total < N) {
00402                 ret = SMB_VFS_WRITE(fsp,fsp->fh->fd,buffer + total,N - total);
00403 
00404                 if (ret == -1)
00405                         return -1;
00406                 if (ret == 0)
00407                         return total;
00408 
00409                 total += ret;
00410         }
00411         return (ssize_t)total;
00412 }

ssize_t vfs_pwrite_data ( files_struct fsp,
const char *  buffer,
size_t  N,
SMB_OFF_T  offset 
)

vfs.c414 行で定義されています。

参照先 fd_handle::fdfiles_struct::fhtotal.

参照元 real_write_file().

00416 {
00417         size_t total=0;
00418         ssize_t ret;
00419 
00420         while (total < N) {
00421                 ret = SMB_VFS_PWRITE(fsp, fsp->fh->fd, buffer + total,
00422                                 N - total, offset + total);
00423 
00424                 if (ret == -1)
00425                         return -1;
00426                 if (ret == 0)
00427                         return total;
00428 
00429                 total += ret;
00430         }
00431         return (ssize_t)total;
00432 }

int vfs_allocate_file_space ( files_struct fsp,
SMB_BIG_UINT  len 
)

vfs.c439 行で定義されています。

参照先 files_struct::connerrnofd_handle::fdfiles_struct::fhflush_write_cache()files_struct::fsp_nameget_dfree_info()release_level_2_oplocks_on_change()set_filelen_write_cache().

参照元 call_nt_transact_create()call_trans2open()reply_ntcreate_and_X()reply_open_and_X()reply_write()smb_set_file_allocation_info().

00440 {
00441         int ret;
00442         SMB_STRUCT_STAT st;
00443         connection_struct *conn = fsp->conn;
00444         SMB_BIG_UINT space_avail;
00445         SMB_BIG_UINT bsize,dfree,dsize;
00446 
00447         release_level_2_oplocks_on_change(fsp);
00448 
00449         /*
00450          * Actually try and commit the space on disk....
00451          */
00452 
00453         DEBUG(10,("vfs_allocate_file_space: file %s, len %.0f\n", fsp->fsp_name, (double)len ));
00454 
00455         if (((SMB_OFF_T)len) < 0) {
00456                 DEBUG(0,("vfs_allocate_file_space: %s negative len requested.\n", fsp->fsp_name ));
00457                 errno = EINVAL;
00458                 return -1;
00459         }
00460 
00461         ret = SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st);
00462         if (ret == -1)
00463                 return ret;
00464 
00465         if (len == (SMB_BIG_UINT)st.st_size)
00466                 return 0;
00467 
00468         if (len < (SMB_BIG_UINT)st.st_size) {
00469                 /* Shrink - use ftruncate. */
00470 
00471                 DEBUG(10,("vfs_allocate_file_space: file %s, shrink. Current size %.0f\n",
00472                                 fsp->fsp_name, (double)st.st_size ));
00473 
00474                 flush_write_cache(fsp, SIZECHANGE_FLUSH);
00475                 if ((ret = SMB_VFS_FTRUNCATE(fsp, fsp->fh->fd, (SMB_OFF_T)len)) != -1) {
00476                         set_filelen_write_cache(fsp, len);
00477                 }
00478                 return ret;
00479         }
00480 
00481         /* Grow - we need to test if we have enough space. */
00482 
00483         if (!lp_strict_allocate(SNUM(fsp->conn)))
00484                 return 0;
00485 
00486         len -= st.st_size;
00487         len /= 1024; /* Len is now number of 1k blocks needed. */
00488         space_avail = get_dfree_info(conn,fsp->fsp_name,False,&bsize,&dfree,&dsize);
00489         if (space_avail == (SMB_BIG_UINT)-1) {
00490                 return -1;
00491         }
00492 
00493         DEBUG(10,("vfs_allocate_file_space: file %s, grow. Current size %.0f, needed blocks = %.0f, space avail = %.0f\n",
00494                         fsp->fsp_name, (double)st.st_size, (double)len, (double)space_avail ));
00495 
00496         if (len > space_avail) {
00497                 errno = ENOSPC;
00498                 return -1;
00499         }
00500 
00501         return 0;
00502 }

int vfs_set_filelen ( files_struct fsp,
SMB_OFF_T  len 
)

vfs.c510 行で定義されています。

参照先 files_struct::connfd_handle::fdfiles_struct::fhflush_write_cache()files_struct::fsp_namenotify_fname()release_level_2_oplocks_on_change()set_filelen_write_cache().

参照元 reply_open_and_X()reply_write()smb_set_file_size().

00511 {
00512         int ret;
00513 
00514         release_level_2_oplocks_on_change(fsp);
00515         DEBUG(10,("vfs_set_filelen: ftruncate %s to len %.0f\n", fsp->fsp_name, (double)len));
00516         flush_write_cache(fsp, SIZECHANGE_FLUSH);
00517         if ((ret = SMB_VFS_FTRUNCATE(fsp, fsp->fh->fd, len)) != -1) {
00518                 set_filelen_write_cache(fsp, len);
00519                 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
00520                              FILE_NOTIFY_CHANGE_SIZE
00521                              | FILE_NOTIFY_CHANGE_ATTRIBUTES,
00522                              fsp->fsp_name);
00523         }
00524 
00525         return ret;
00526 }

int vfs_fill_sparse ( files_struct fsp,
SMB_OFF_T  len 
)

vfs.c538 行で定義されています。

参照先 errnofd_handle::fdfiles_struct::fhflush_write_cache()files_struct::fsp_namerelease_level_2_oplocks_on_change()set_filelen_write_cache()sparse_bufstrerror()total.

参照元 real_write_file().

00539 {
00540         int ret;
00541         SMB_STRUCT_STAT st;
00542         SMB_OFF_T offset;
00543         size_t total;
00544         size_t num_to_write;
00545         ssize_t pwrite_ret;
00546 
00547         release_level_2_oplocks_on_change(fsp);
00548         ret = SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st);
00549         if (ret == -1) {
00550                 return ret;
00551         }
00552 
00553         if (len <= st.st_size) {
00554                 return 0;
00555         }
00556 
00557         DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to len %.0f (%.0f bytes)\n",
00558                 fsp->fsp_name, (double)st.st_size, (double)len, (double)(len - st.st_size)));
00559 
00560         flush_write_cache(fsp, SIZECHANGE_FLUSH);
00561 
00562         if (!sparse_buf) {
00563                 sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE);
00564                 if (!sparse_buf) {
00565                         errno = ENOMEM;
00566                         return -1;
00567                 }
00568         }
00569 
00570         offset = st.st_size;
00571         num_to_write = len - st.st_size;
00572         total = 0;
00573 
00574         while (total < num_to_write) {
00575                 size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (num_to_write - total));
00576 
00577                 pwrite_ret = SMB_VFS_PWRITE(fsp, fsp->fh->fd, sparse_buf, curr_write_size, offset + total);
00578                 if (pwrite_ret == -1) {
00579                         DEBUG(10,("vfs_fill_sparse: SMB_VFS_PWRITE for file %s failed with error %s\n",
00580                                 fsp->fsp_name, strerror(errno) ));
00581                         return -1;
00582                 }
00583                 if (pwrite_ret == 0) {
00584                         return 0;
00585                 }
00586 
00587                 total += pwrite_ret;
00588         }
00589 
00590         set_filelen_write_cache(fsp, len);
00591         return 0;
00592 }

static ssize_t read_fn ( int  fd,
void *  buf,
size_t  len 
) [static]

vfs.c601 行で定義されています。

参照先 in_fsp.

参照元 vfs_transfer_file().

00602 {
00603         return SMB_VFS_READ(in_fsp, fd, buf, len);
00604 }

static ssize_t write_fn ( int  fd,
const void *  buf,
size_t  len 
) [static]

vfs.c606 行で定義されています。

参照先 out_fsp.

参照元 vfs_transfer_file().

00607 {
00608         return SMB_VFS_WRITE(out_fsp, fd, buf, len);
00609 }

SMB_OFF_T vfs_transfer_file ( files_struct in,
files_struct out,
SMB_OFF_T  n 
)

vfs.c611 行で定義されています。

参照先 fd_handle::fdfiles_struct::fhin_fspout_fspread_fn()transfer_file_internal()write_fn().

参照元 copy_file()copy_internals().

00612 {
00613         in_fsp = in;
00614         out_fsp = out;
00615 
00616         return transfer_file_internal(in_fsp->fh->fd, out_fsp->fh->fd, n, read_fn, write_fn);
00617 }

char* vfs_readdirname ( connection_struct conn,
void *  p 
)

vfs.c623 行で定義されています。

参照先 telldir().

参照元 form_junctions()ReadDirName().

00624 {
00625         SMB_STRUCT_DIRENT *ptr= NULL;
00626         char *dname;
00627 
00628         if (!p)
00629                 return(NULL);
00630 
00631         ptr = SMB_VFS_READDIR(conn, (DIR *)p);
00632         if (!ptr)
00633                 return(NULL);
00634 
00635         dname = ptr->d_name;
00636 
00637 #ifdef NEXT2
00638         if (telldir(p) < 0)
00639                 return(NULL);
00640 #endif
00641 
00642 #ifdef HAVE_BROKEN_READDIR_NAME
00643         /* using /usr/ucb/cc is BAD */
00644         dname = dname - 2;
00645 #endif
00646 
00647         return(dname);
00648 }

int vfs_ChDir ( connection_struct conn,
const char *  path 
)

vfs.c654 行で定義されています。

参照先 strcsequal().

参照元 _dfs_Add()_dfs_Enum()_dfs_GetInfo()_dfs_Remove()change_dir_owner_to_parent()close_cnum()create_conn_struct()make_connection_with_chdir()set_current_service()setup_dfs_referral().

00655 {
00656         int res;
00657         static pstring LastDir="";
00658 
00659         if (strcsequal(path,"."))
00660                 return(0);
00661 
00662         if (*path == '/' && strcsequal(LastDir,path))
00663                 return(0);
00664 
00665         DEBUG(4,("vfs_ChDir to %s\n",path));
00666 
00667         res = SMB_VFS_CHDIR(conn,path);
00668         if (!res)
00669                 pstrcpy(LastDir,path);
00670         return(res);
00671 }

static void array_promote ( char *  array,
int  elsize,
int  element 
) [static]

vfs.c689 行で定義されています。

参照元 vfs_GetWd().

00690 {
00691         char *p;
00692         if (element == 0)
00693                 return;
00694 
00695         p = (char *)SMB_MALLOC(elsize);
00696 
00697         if (!p) {
00698                 DEBUG(5,("array_promote: malloc fail\n"));
00699                 return;
00700         }
00701 
00702         memcpy(p,array + element * elsize, elsize);
00703         memmove(array + elsize,array,elsize*element);
00704         memcpy(array,p,elsize);
00705         SAFE_FREE(p);
00706 }

char* vfs_GetWd ( connection_struct conn,
char *  path 
)

vfs.c714 行で定義されています。

参照先 array_promote()dos_patherrnoino_liststrerror()string_set()use_getwd_cachevalid.

参照元 change_dir_owner_to_parent().

00715 {
00716         pstring s;
00717         static BOOL getwd_cache_init = False;
00718         SMB_STRUCT_STAT st, st2;
00719         int i;
00720 
00721         *s = 0;
00722 
00723         if (!use_getwd_cache)
00724                 return(SMB_VFS_GETWD(conn,path));
00725 
00726         /* init the cache */
00727         if (!getwd_cache_init) {
00728                 getwd_cache_init = True;
00729                 for (i=0;i<MAX_GETWDCACHE;i++) {
00730                         string_set(&ino_list[i].dos_path,"");
00731                         ino_list[i].valid = False;
00732                 }
00733         }
00734 
00735         /*  Get the inode of the current directory, if this doesn't work we're
00736                 in trouble :-) */
00737 
00738         if (SMB_VFS_STAT(conn, ".",&st) == -1) {
00739                 /* Known to fail for root: the directory may be
00740                  * NFS-mounted and exported with root_squash (so has no root access). */
00741                 DEBUG(1,("vfs_GetWd: couldn't stat \".\" path=%s error %s (NFS problem ?)\n", path, strerror(errno) ));
00742                 return(SMB_VFS_GETWD(conn,path));
00743         }
00744 
00745 
00746         for (i=0; i<MAX_GETWDCACHE; i++) {
00747                 if (ino_list[i].valid) {
00748 
00749                         /*  If we have found an entry with a matching inode and dev number
00750                                 then find the inode number for the directory in the cached string.
00751                                 If this agrees with that returned by the stat for the current
00752                                 directory then all is o.k. (but make sure it is a directory all
00753                                 the same...) */
00754 
00755                         if (st.st_ino == ino_list[i].inode && st.st_dev == ino_list[i].dev) {
00756                                 if (SMB_VFS_STAT(conn,ino_list[i].dos_path,&st2) == 0) {
00757                                         if (st.st_ino == st2.st_ino && st.st_dev == st2.st_dev &&
00758                                                         (st2.st_mode & S_IFMT) == S_IFDIR) {
00759                                                 pstrcpy (path, ino_list[i].dos_path);
00760 
00761                                                 /* promote it for future use */
00762                                                 array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
00763                                                 return (path);
00764                                         } else {
00765                                                 /*  If the inode is different then something's changed,
00766                                                         scrub the entry and start from scratch. */
00767                                                 ino_list[i].valid = False;
00768                                         }
00769                                 }
00770                         }
00771                 }
00772         }
00773 
00774         /*  We don't have the information to hand so rely on traditional methods.
00775                 The very slow getcwd, which spawns a process on some systems, or the
00776                 not quite so bad getwd. */
00777 
00778         if (!SMB_VFS_GETWD(conn,s)) {
00779                 DEBUG(0,("vfs_GetWd: SMB_VFS_GETWD call failed, errno %s\n",strerror(errno)));
00780                 return (NULL);
00781         }
00782 
00783         pstrcpy(path,s);
00784 
00785         DEBUG(5,("vfs_GetWd %s, inode %.0f, dev %.0f\n",s,(double)st.st_ino,(double)st.st_dev));
00786 
00787         /* add it to the cache */
00788         i = MAX_GETWDCACHE - 1;
00789         string_set(&ino_list[i].dos_path,s);
00790         ino_list[i].dev = st.st_dev;
00791         ino_list[i].inode = st.st_ino;
00792         ino_list[i].valid = True;
00793 
00794         /* put it at the top of the list */
00795         array_promote((char *)&ino_list[0],sizeof(ino_list[0]),i);
00796 
00797         return (path);
00798 }

NTSTATUS reduce_name ( connection_struct conn,
const pstring  fname 
)

vfs.c805 行で定義されています。

参照先 connection_struct::connectpatherrnomap_nt_error_from_unix()strrchr_m().

参照元 check_name()copy_internals()hardlink_internals().

00806 {
00807 #ifdef REALPATH_TAKES_NULL
00808         BOOL free_resolved_name = True;
00809 #else
00810 #ifdef PATH_MAX
00811         char resolved_name_buf[PATH_MAX+1];
00812 #else
00813         pstring resolved_name_buf;
00814 #endif
00815         BOOL free_resolved_name = False;
00816 #endif
00817         char *resolved_name = NULL;
00818         size_t con_path_len = strlen(conn->connectpath);
00819         char *p = NULL;
00820 
00821         DEBUG(3,("reduce_name [%s] [%s]\n", fname, conn->connectpath));
00822 
00823 #ifdef REALPATH_TAKES_NULL
00824         resolved_name = SMB_VFS_REALPATH(conn,fname,NULL);
00825 #else
00826         resolved_name = SMB_VFS_REALPATH(conn,fname,resolved_name_buf);
00827 #endif
00828 
00829         if (!resolved_name) {
00830                 switch (errno) {
00831                         case ENOTDIR:
00832                                 DEBUG(3,("reduce_name: Component not a directory in getting realpath for %s\n", fname));
00833                                 return map_nt_error_from_unix(errno);
00834                         case ENOENT:
00835                         {
00836                                 pstring tmp_fname;
00837                                 fstring last_component;
00838                                 /* Last component didn't exist. Remove it and try and canonicalise the directory. */
00839 
00840                                 pstrcpy(tmp_fname, fname);
00841                                 p = strrchr_m(tmp_fname, '/');
00842                                 if (p) {
00843                                         *p++ = '\0';
00844                                         fstrcpy(last_component, p);
00845                                 } else {
00846                                         fstrcpy(last_component, tmp_fname);
00847                                         pstrcpy(tmp_fname, ".");
00848                                 }
00849 
00850 #ifdef REALPATH_TAKES_NULL
00851                                 resolved_name = SMB_VFS_REALPATH(conn,tmp_fname,NULL);
00852 #else
00853                                 resolved_name = SMB_VFS_REALPATH(conn,tmp_fname,resolved_name_buf);
00854 #endif
00855                                 if (!resolved_name) {
00856                                         DEBUG(3,("reduce_name: couldn't get realpath for %s\n", fname));
00857                                         return map_nt_error_from_unix(errno);
00858                                 }
00859                                 pstrcpy(tmp_fname, resolved_name);
00860                                 pstrcat(tmp_fname, "/");
00861                                 pstrcat(tmp_fname, last_component);
00862 #ifdef REALPATH_TAKES_NULL
00863                                 SAFE_FREE(resolved_name);
00864                                 resolved_name = SMB_STRDUP(tmp_fname);
00865                                 if (!resolved_name) {
00866                                         DEBUG(0,("reduce_name: malloc fail for %s\n", tmp_fname));
00867                                         return NT_STATUS_NO_MEMORY;
00868                                 }
00869 #else
00870 #ifdef PATH_MAX
00871                                 safe_strcpy(resolved_name_buf, tmp_fname, PATH_MAX);
00872 #else
00873                                 pstrcpy(resolved_name_buf, tmp_fname);
00874 #endif
00875                                 resolved_name = resolved_name_buf;
00876 #endif
00877                                 break;
00878                         }
00879                         default:
00880                                 DEBUG(1,("reduce_name: couldn't get realpath for %s\n", fname));
00881                                 return map_nt_error_from_unix(errno);
00882                 }
00883         }
00884 
00885         DEBUG(10,("reduce_name realpath [%s] -> [%s]\n", fname, resolved_name));
00886 
00887         if (*resolved_name != '/') {
00888                 DEBUG(0,("reduce_name: realpath doesn't return absolute paths !\n"));
00889                 if (free_resolved_name) {
00890                         SAFE_FREE(resolved_name);
00891                 }
00892                 return NT_STATUS_OBJECT_NAME_INVALID;
00893         }
00894 
00895         /* Check for widelinks allowed. */
00896         if (!lp_widelinks(SNUM(conn)) && (strncmp(conn->connectpath, resolved_name, con_path_len) != 0)) {
00897                 DEBUG(2, ("reduce_name: Bad access attempt: %s is a symlink outside the share path", fname));
00898                 if (free_resolved_name) {
00899                         SAFE_FREE(resolved_name);
00900                 }
00901                 return NT_STATUS_ACCESS_DENIED;
00902         }
00903 
00904         /* Check if we are allowing users to follow symlinks */
00905         /* Patch from David Clerc <David.Clerc@cui.unige.ch>
00906                 University of Geneva */
00907                                                                                                                                                     
00908 #ifdef S_ISLNK
00909         if (!lp_symlinks(SNUM(conn))) {
00910                 SMB_STRUCT_STAT statbuf;
00911                 if ( (SMB_VFS_LSTAT(conn,fname,&statbuf) != -1) &&
00912                                 (S_ISLNK(statbuf.st_mode)) ) {
00913                         if (free_resolved_name) {
00914                                 SAFE_FREE(resolved_name);
00915                         }
00916                         DEBUG(3,("reduce_name: denied: file path name %s is a symlink\n",resolved_name));
00917                         return NT_STATUS_ACCESS_DENIED;
00918                 }
00919         }
00920 #endif
00921 
00922         DEBUG(3,("reduce_name: %s reduced to %s\n", fname, resolved_name));
00923         if (free_resolved_name) {
00924                 SAFE_FREE(resolved_name);
00925         }
00926         return NT_STATUS_OK;
00927 }


変数

static_decl_vfs

vfs.c31 行で定義されています。

struct vfs_init_function_entry* backends = NULL [static]

vfs.c39 行で定義されています。

char* sparse_buf [static]

vfs.c535 行で定義されています。

参照元 vfs_fill_sparse().

files_struct* in_fsp [static]

vfs.c598 行で定義されています。

参照元 read_fn()vfs_transfer_file().

files_struct* out_fsp [static]

vfs.c599 行で定義されています。

参照元 vfs_transfer_file()write_fn().

SMB_DEV_T dev

vfs.c677 行で定義されています。

参照元 cmd_mknod()downgrade_oplock()free_dev_mode()make_connection()make_connection_snum()msg_file_was_renamed()open_file_ntcreate()process_kernel_oplock_break()remove_oplock()reply_tcon()smb_unix_mknod().

SMB_INO_T inode

vfs.c678 行で定義されています。

参照元 call_trans2open()dos_attr_query()downgrade_oplock()msg_file_was_renamed()open_file_ntcreate()process_kernel_oplock_break()remove_oplock().

char* dos_path

vfs.c679 行で定義されています。

参照元 vfs_GetWd().

BOOL valid

vfs.c680 行で定義されています。

参照元 _lsa_lookup_sids_internal()copy_print_driver_3()display_print_driver_3()lookup_sids()torture_utable()user_ok()vfs_GetWd().

struct { ... } ino_list[MAX_GETWDCACHE] [static]

参照元 vfs_GetWd().

BOOL use_getwd_cache

loadparm.c83 行で定義されています。

参照元 vfs_GetWd().


Sambaに対してSat Aug 29 21:24:30 2009に生成されました。  doxygen 1.4.7